int __fastcall main(int argc, const char **argv, const char **envp)
{
puts(&s);
puts("# Program Description");
puts(" - I have so many functions. (func_0, func_1, ..., func_927)");
puts(" - Each function has 1 characater as local variable.");
puts(&s);
puts("# To Do");
puts("1. Collect those characters and convert them as a string.");
puts("2. Find DH{[a-z0-9][32]} from the string!");
puts(&s);
return 0;
}
문제 설명처럼 func_0부터 func_927까지 순차적으로 실행시켜서 플래그를 얻으면 된다.
근데 어떻게...?
수많은 시행착오 끝에 기틀을 마련했다.
import gdb
ge = gdb.execute
ge("file ./collect_me")
addr = str(gdb.parse_and_eval('func_900').address).split()[0]
print(int(addr,16))
gdb.parse_and_eval을 활용하면 gdb.Value로 값을 받는다. 그래서 address로 앞의 설명을 한 번 걸러주고 split을 통해 함수명과 주소를 분리한 뒤, str로 타입 변경을 한다. 마지막으로 주소가 0번째 인덱스이기 때문에 [0]로 주소를 따로 빼낸다. (수정이 가능한 값이 아니기 때문에 list로 바로 변환은 힘들다.)

addr + 0xc에 breakpoint를 걸고 rbp-1에 저장된 값을 찾으면 된다.
아니지, 애초에 저 func에 갈 일도 없으니까 그냥 저 주소값을 가져오면 된다.

11만큼 차이나는 위치에 저장되어 있다.
import gdb
ge = gdb.execute
inferior = gdb.selected_inferior()
ge("file ./collect_me")
f = 'func_'
flag = b''
for i in range(928):
addr = int(str(gdb.parse_and_eval(f+str(i)).address).split()[0], 16)
val = bytes(inferior.read_memory(addr+0xb, 1))
flag += val
print(flag)
