2016-09-16 5 views
2

저는 할당 된 간단한 난독 화 C 프로그램의 다음 ASM 코드를 가지고 있습니다.ELF 바이너리에서 asm 명령어를 수정하십시오.

0x00000000004006a0 <+147>: lea -0x20(%rbp),%rax 
    0x00000000004006a4 <+151>: mov %rdx,%rsi 
    0x00000000004006a7 <+154>: mov %rax,%rdi 
    0x00000000004006aa <+157>: callq 0x400713 <SECRET> <====== 
    0x00000000004006af <+162>: movl $0x0,-0x24(%rbp) 
    0x00000000004006b6 <+169>: jmp 0x4006d8 <main+203> 
    0x00000000004006b8 <+171>: mov -0x24(%rbp),%eax 

목표는 세그먼트 화 오류를 일으키는 기능 (프로그램 바이너리를 패치)을 찾아서 제거하는 것입니다. 어떤 기능이 segfault를 일으키는 지 알게되었지만 바이너리를 패치하는 방법을 모르겠습니다.

내 문제는 내가 늘 비밀 함수를 호출 할 수 있도록

0x00000000004006aa <+157>: callq 0x400713 <SECRET> 

을 패치하는 방법이다.

gdb을 사용하면 런타임시 단일 단계에서 프로그램 카운터를 수정하여 SECRET을 건너 뛰거나 건너 뛰기 위해 프로그램이 실행을 끝내고 원하는 출력을 제공합니다.

내가 원하는 것은 항상 디버거를 사용하지 않고 건너 뛸 수있는 실행 가능 바이너리 파일의 영구적으로 수정 된 복사본입니다.

+0

거기에 건너 뛰거나 gdb없이 프로그램을 실행할 때 점프하는 방법이 있습니다 –

+0

GDB에서 건너 뛰는 것은 과제를 해결하는 것으로 계산되지 않지만 예, gdb는 원하는 곳으로 점프 할 수 있습니다. gdb 매뉴얼을 확인하십시오. 디버깅 세션 중에 NOP로'call' 명령을 덮어 쓸 수도 있습니다. 이것이 바이너리 폭탄 실험실 과제와 같은 것이라면, 당신은 다른 입력을 주어야합니다. 그래서 실행은 결코 그 블록에 도달하지 못합니다. –

+0

그래, 나는 프로그램 카운터와 함께 할 수 있지만, 바이너리를 편집하고 그 함수 호출을 제거하고 패치 된 파일을 저장하는 방법을 찾고있다. –

답변

1

내가 GDB로 할 수있는 일에 대해 궁금했다. 필자는 GDB를 사용하여 어셈블리를 변경할 수 있었고 패치 프로그램은 제대로 작동했습니다.

nop을 사용해 보았지만 작동하지 않아 기능을 뛰어 넘었습니다. 패치의 작동 방식은 다음과 같습니다.

(gdb) set {unsigned char *}0x4006aa = 0xEB 
(gdb) set {unsigned char *}0x4006ab = 0x0C 

나는 짧은 도약을하고 있습니다. 짧은 점프 opcode는 EB XX입니다. 여기서 XX는 IP/PC에서 상대 점프입니다. 이 경우 나는 12 바이트 앞으로 도약해야하며, 명령은 2 바이트이기 때문에 연속적인 메모리 위치에 씁니다. 나는 새롭게 수정 된 바이너리를 하드 드라이브와 모든 것에 썼다.

실험의 날이 걸렸지 만 결국에는 많은 것을 배웠습니다. : D

+1

당신은 아마도'set {unsigned short *} 0x4006aa = 0x0CEB'도 할 수 있습니다. –

+1

이렇게 처음으로 나에게 한 걸음 한걸음 한걸음 한걸음 한걸음 한걸음 내딛었습니다. –