IT Share you

GDB로 메모리 범위를 분해하는 방법은 무엇입니까?

shareyou 2020. 12. 9. 21:57
반응형

GDB로 메모리 범위를 분해하는 방법은 무엇입니까?


나는 syscall 어셈블리 명령 (내 생각에 INT 명령)과 GDB의 핸들러를보기 위해 프로그램을 분해하려고하고 파일을 열고 닫는 작은 프로그램 (아래 참조)을 작성했습니다.

나는 호출을 실행할 때까지 GDB로 fopen 호출을 따를 수 있었다.

내가 GDB에 "disassemble 0x ...."(호출 주소)를 알리려고했을 때 'No function contains specified address'로 응답했습니다.

GDB가 해당 메모리 주소를 디스 어셈블하거나 가능한 한 어셈블러에 표시하도록 강제 할 수 있습니까? 그렇다면 어떻게?

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE* f;
    f = fopen("main.c", "r");
    if (!f) { 
      perror("open");
      return -1;
    }
    fclose(f);
    return 0;
}

실제 메인 만 분해 하시겠습니까? 그렇다면 이것을 시도하십시오.

(gdb) info line main 
(gdb) disas STARTADDRESS ENDADDRESS

이렇게 :

USER@MACHINE /cygdrive/c/prog/dsa
$ gcc-3.exe -g main.c

USER@MACHINE /cygdrive/c/prog/dsa
$ gdb a.exe
GNU gdb 6.8.0.20080328-cvs (cygwin-special)
...
(gdb) info line main
Line 3 of "main.c" starts at address 0x401050 <main> and ends at 0x401075 <main+
(gdb) disas 0x401050 0x401075
Dump of assembler code from 0x401050 to 0x401075:
0x00401050 <main+0>:    push   %ebp
0x00401051 <main+1>:    mov    %esp,%ebp
0x00401053 <main+3>:    sub    $0x18,%esp
0x00401056 <main+6>:    and    $0xfffffff0,%esp
0x00401059 <main+9>:    mov    $0x0,%eax
0x0040105e <main+14>:   add    $0xf,%eax
0x00401061 <main+17>:   add    $0xf,%eax
0x00401064 <main+20>:   shr    $0x4,%eax
0x00401067 <main+23>:   shl    $0x4,%eax
0x0040106a <main+26>:   mov    %eax,-0xc(%ebp)
0x0040106d <main+29>:   mov    -0xc(%ebp),%eax
0x00401070 <main+32>:   call   0x4010c4 <_alloca>
End of assembler dump.

그러나 시스템 인터럽트 호출이 보이지 않습니다. (내가 어셈블리에서 시스템 호출을 마지막으로 시도한 지 오래되었습니다. INT 21h 그래도 마지막으로 기억합니다.


예, 분해는 여기서 사용하는 가장 좋은 명령이 아닙니다. 원하는 명령은 "x / i"입니다 (지침으로 조사).

(gdb) x/i 0xdeadbeef

이것은 귀하의 질문에 대한 직접적인 대답은 아니지만 바이너리를 분해하려는 것 같기 때문에 아마도 다음을 사용할 수 있습니다 objdump.

objdump -d program

이것은 분해를 제공합니다. -S소스 주석을 추가 하려면 추가 수 있습니다 .


fopen ()은 C 라이브러리 함수이므로 코드에 syscall 명령이 표시되지 않고 일반 함수 호출 만 표시됩니다. 어느 시점에서 open (2)를 호출하지만 트램폴린을 통해 수행합니다. 커널이 모든 프로세스에 제공하는 VDSO 페이지로 이동하기 만하면됩니다. 그런 다음 VDSO는 시스템 호출을위한 코드를 제공합니다. 최신 프로세서에서는 SYSCALL 또는 SYSENTER 명령어가 사용되지만 x86 프로세서에서 INT 80h를 사용할 수도 있습니다.


You can force gcc to output directly to assembly code by adding the -S switch

gcc -S hello.c

If all that you want is to see the disassembly with the INTC call, use objdump -d as someone mentioned but use the -static option when compiling. Otherwise the fopen function is not compiled into the elf and is linked at runtime.


You don't have to use gdb. GCC will do it.

 gcc -S foo.c

This will create foo.s which is the assembly.

gcc -m32 -c -g -Wa,-a,-ad foo.c > foo.lst

The above version will create a listing file that has both the C and the assembly generated by it. GCC FAQ


gdb disassemble has a /m to include source code alongside the instructions. This is equivalent of objdump -S, with the extra benefit of confining to just the one function (or address-range) of interest.

참고URL : https://stackoverflow.com/questions/1237489/how-to-disassemble-a-memory-range-with-gdb

반응형