[linux] 지정된 실행 파일 외부의 단일 단계 어셈블리 코드에 gdb를 사용하면 “현재 함수의 범위를 찾을 수 없습니다”오류가 발생합니다.

나는 gdb의 대상 실행 파일 외부에 있으며 해당 대상에 해당하는 스택도 없습니다. 어쨌든 나는 x86 어셈블리의 전문가가 아니기 때문에 어셈블리 코드에서 무슨 일이 일어나고 있는지 확인할 수 있도록 한 단계 씩 진행하고 싶습니다. 불행히도 gdb는이 간단한 어셈블리 수준 디버깅을 거부합니다. 적절한 중단 점을 설정하고 중지 할 수 있지만 한 단계 진행하자마자 gdb는 “현재 함수의 경계를 찾을 수 없습니다”라는 오류를보고하고 EIP는 변경되지 않습니다.

추가 세부 사항:

기계 코드는 gcc asm 문에 의해 생성되었으며 objdump -d의 출력에서 ​​실행중인 커널 메모리 위치에 복사했습니다. 로더를 사용하여 객체 코드를 재배치 된 주소로로드하는 간단한 방법은 신경 쓰지 않지만로드는 커널 모듈에서 수행해야합니다.

또 다른 대안은 gdb에 제공 할 가짜 커널 모듈 또는 디버그 정보 파일을 생성하여이 영역이 프로그램 코드 내에 있다고 믿도록하는 것입니다. gdb는 커널 실행 파일 자체에서 잘 작동합니다.

(정말 알고 싶은 사람들을 위해 런타임에 VMware VM 내부의 Linux 커널 데이터 공간에 코드를 삽입하고 VMware Workstation의 내장 gdb 스텁을 통해 커널을 원격 디버깅하는 gdb에서 디버깅합니다. 참고 커널을 작성하는 것이 아닙니다. 익스플로잇; 저는 프로토 타입을 작성하는 보안 대학원생입니다.)

(내 어셈블리 내부의 각 명령어에 중단 점을 설정할 수 있습니다. 이것은 작동하지만 x86 어셈블리 명령어의 크기가 다양하고 재부팅 할 때마다 어셈블리 위치가 변경되기 때문에 시간이 지나면 상당히 힘들 것입니다.)



답변

당신이 사용할 수있는 stepi 또는 nexti(이는로 축약 할 수 있습니다 si또는 ni컴퓨터 코드를 통해 단계).


답변

대신 gdb, 실행 gdbtui. 또는 스위치로 실행 gdb하십시오 -tui. 또는 C-x C-a입력 후를 누릅니다 gdb. 이제 GDB의 TUI 모드에 있습니다.

Enter 키 layout asm를 눌러 상단 창 디스플레이 어셈블리를 만듭니다. 디버깅하는 동안 프레임을 변경하거나 스크롤 할 수도 있지만 자동으로 명령 포인터를 따릅니다. 을 눌러 단일 키 C-x s모드로 들어가십시오. 여기서 run continue up down finish등은 단일 키로 축약되어 프로그램을 매우 빠르게 진행할 수 있습니다.

   + ------------------------------------------------- -------------------------- +
B +> | 0x402670 <main> 푸시 % r15 |
   | 0x402672 <main + 2> mov % edi, % r15d |
   | 0x402675 <main + 5> 푸시 % r14 |
   | 0x402677 <main + 7> 푸시 % r13 |
   | 0x402679 <main + 9> mov % rsi, % r13 |
   | 0x40267c <main + 12> 푸시 % r12 |
   | 0x40267e <main + 14> % rbp 푸시 |
   | 0x40267f <main + 15> % rbx 푸시 |
   | 0x402680 <메인 +16> 하위 $ 0x438, % rsp |
   | 0x402687 <main + 23> mov (% rsi), % rdi |
   | 0x40268a <main + 26> movq $ 0x402a10,0x400 (% rsp) |
   | 0x402696 <main + 38> movq $ 0x0,0x408 (% rsp) |
   | 0x4026a2 <main + 50> movq $ 0x402510,0x410 (% rsp) |
   + ------------------------------------------------- -------------------------- +
자식 프로세스 21518 In : 메인 라인 : ?? PC : 0x402670
(gdb) 파일 / opt / j64-602 / bin / jconsole
/ opt / j64-602 / bin / jconsole에서 기호 읽기 ... 완료.
(디버깅 기호가 없음) ... 완료.
(gdb) 레이아웃 asm
(gdb) 시작
(gdb)


답변

여기서 할 수있는 가장 유용한 것은 R Samuel Klatchko의 답변에서 이미 제안 된대로 display/i $pc사용하기 전에 stepi입니다. 이것은 매번 프롬프트를 인쇄하기 직전에 gdb에게 현재 명령어를 디스 어셈블하도록 지시합니다. 그런 다음 Enter 키를 계속 눌러 stepi명령 을 반복 할 수 있습니다 .

(자세한 내용 은 다른 질문에 대한 내 답변을 참조하십시오. 해당 질문의 컨텍스트는 달랐지만 원칙은 동일합니다.)


답변