This question already has answers here:
GDB Cannot insert breakpoint, Cannot access memory at address XXX? [duplicate]
(2 answers)
Closed 5 years ago.
Dump of assembler code for function main():
0x000000000000071a <+0>: push rbp
0x000000000000071b <+1>: mov rbp,rsp
0x000000000000071e <+4>: sub rsp,0x20
0x0000000000000722 <+8>: mov rax,QWORD PTR fs:0x28
0x000000000000072b <+17>: mov QWORD PTR [rbp-0x8],rax
0x000000000000072f <+21>: xor eax,eax
0x0000000000000731 <+23>: lea rax,[rbp-0x20]
0x0000000000000735 <+27>: mov rdi,rax
0x0000000000000738 <+30>: call 0x764 <Test::Test()>
0x000000000000073d <+35>: lea rax,[rbp-0x20]
0x0000000000000741 <+39>: mov rdi,rax
0x0000000000000744 <+42>: call 0x7ae <Test::a()>
0x0000000000000749 <+47>: mov eax,0x0
0x000000000000074e <+52>: mov rdx,QWORD PTR [rbp-0x8]
0x0000000000000752 <+56>: xor rdx,QWORD PTR fs:0x28
0x000000000000075b <+65>: je 0x762 <main()+72>
0x000000000000075d <+67>: call 0x5f0 <__stack_chk_fail#plt>
0x0000000000000762 <+72>: leave
0x0000000000000763 <+73>: ret
End of assembler dump.
I have a problem.. I'm trying to debug the program but the addresses are weird and I can't read the registers(after start). "The program has no registers now."
and that's happens at any program that I've compiled in my computer.
EDIT:
gef➤ break*0x0000000000000763
Breakpoint 1 at 0x763: file 1.cpp, line 36.
gef➤ r
Starting program: /root/Desktop/Challenges/AdvancedMemoryChallenges/1.bin
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x763
gef➤ info reg $rip
rip 0x7ffff7dd9c20 0x7ffff7dd9c20
gef➤
gef➤ start
[+] Breaking at '{int (void)} 0x55555555471a <main()>'
[!] Command 'entry-break' failed to execute properly, reason: Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x763
0x763 is an address before relocation. (It is unclear whether it is from an object file or the actual executable.)
The addresses of code in a running program are never this low in the address space.
You need to set a breakpoint on _start or main, start the program, and see which addresses the kernel assigns to the machine code in question. The GDB disassemble command print will print such addresses.
GDB automatically disables address space layout randomization (ASLR), so the addresses will be constant as long as you do not change the program, its libraries, or the kernel (which sometimes results in process layout changes, too).
Is it possible to examine memory as instruction (x/i) the way I can see both asm and raw instructions in hex (like with disassemble /r)?
Sometimes I want to disassemble some part of memory which GDB refuses to disassemble saying: "No function contains specified address".
The only option is then x/i, but I would like to see exactly what hex values are translated to what instructions.
I want to disassemble some part of memory which GDB refuses to disassemble saying: "No function contains specified address".
The disas/r 0x1234,0x1235 will work even when GDB can not determine function boundaries. Example:
(gdb) disas/r 0x0000000000400803
No function contains specified address.
(gdb) disas/r 0x0000000000400803,0x000000000040080f
Dump of assembler code from 0x400803 to 0x40080f:
0x0000000000400803: e8 b8 fd ff ff callq 0x4005c0 <system#plt>
0x0000000000400808: 48 81 45 f0 00 10 00 00 addq $0x1000,-0x10(%rbp)
End of assembler dump.
When I debugged a code, and found:
0x08048500 <+0>: push %ebp
0x08048501 <+1>: mov %esp,%ebp
...
0x08048563 <+99>: jmp 0x8048567 <Postion+103> <===0x8048567 doesn't exist an instruction.
0x08048565 <+101>: dec %edx
0x08048566 <+102>: cmp %bh,%al
0x08048568 <+104>: test %edx,%esp
Q: Why does "jmp 0x8048567" jump into <+103>? It doesn't exist an instruction. What's the point? Thanks.
Why does "jmp 0x8048567" jump into <+103>? It doesn't exist an instruction
It's very likely that the instruction at 0x8048567 does exist. You can see it with x/4i 0x8048567.
What is probably happening is that instruction at 0x8048565 doesn't really exist, but GDB doesn't know that, continues disassembling one instruction after another, and gets out of sync with the real instruction stream.
I ran the debugger on CodeBlocks and viewed the disassembly window.
The full source code for the program I debugged is the following:
int main(){}
and the assembly code I saw in the window was this:
00401020 push %ebp
00401021 mov %esp,%ebp
00401023 push %ebx
00401024 sub $0x34,%esp
00401027 movl $0x401150,(%esp)
0040102E call 0x401984 <SetUnhandledExceptionFilter#4>
00401033 sub $0x4,%esp
00401036 call 0x401330 <__cpu_features_init>
0040103B call 0x401740 <fpreset>
00401040 lea -0x10(%ebp),%eax
00401043 movl $0x0,-0x10(%ebp)
0040104A mov %eax,0x10(%esp)
0040104E mov 0x402000,%eax
00401053 movl $0x404004,0x4(%esp)
0040105B movl $0x404000,(%esp)
00401062 mov %eax,0xc(%esp)
00401066 lea -0xc(%ebp),%eax
00401069 mov %eax,0x8(%esp)
0040106D call 0x40192c <__getmainargs>
00401072 mov 0x404008,%eax
00401077 test %eax,%eax
00401079 jne 0x4010c5 <__mingw_CRTStartup+165>
0040107B call 0x401934 <__p__fmode>
00401080 mov 0x402004,%edx
00401086 mov %edx,(%eax)
00401088 call 0x4014f0 <_pei386_runtime_relocator>
0040108D and $0xfffffff0,%esp
00401090 call 0x401720 <__main>
00401095 call 0x40193c <__p__environ>
0040109A mov (%eax),%eax
0040109C mov %eax,0x8(%esp)
004010A0 mov 0x404004,%eax
004010A5 mov %eax,0x4(%esp)
004010A9 mov 0x404000,%eax
004010AE mov %eax,(%esp)
004010B1 call 0x401318 <main>
004010B6 mov %eax,%ebx
004010B8 call 0x401944 <_cexit>
004010BD mov %ebx,(%esp)
004010C0 call 0x40198c <ExitProcess#4>
004010C5 mov 0x4050f4,%ebx
004010CB mov %eax,0x402004
004010D0 mov %eax,0x4(%esp)
004010D4 mov 0x10(%ebx),%eax
004010D7 mov %eax,(%esp)
004010DA call 0x40194c <_setmode>
004010DF mov 0x404008,%eax
004010E4 mov %eax,0x4(%esp)
004010E8 mov 0x30(%ebx),%eax
004010EB mov %eax,(%esp)
004010EE call 0x40194c <_setmode>
004010F3 mov 0x404008,%eax
004010F8 mov %eax,0x4(%esp)
004010FC mov 0x50(%ebx),%eax
004010FF mov %eax,(%esp)
00401102 call 0x40194c <_setmode>
00401107 jmp 0x40107b <__mingw_CRTStartup+91>
0040110C lea 0x0(%esi,%eiz,1),%esi
Is it normal to get this much assembly code from so little C++ code?
By normal, I mean is this close to the average amount of assembly code the MinGW compiler generates relative to the amount of C++ source code I provided above?
Yes, this is fairly typical startup/shutdown code.
Before your main runs, a few things need to happen:
stdin/stdout/stderr get opened
cin/cout/cerr/clog get opened, referring to stdin/stdout/stderr
Any static objects you define get initialized
command line gets parsed to produce argc/argv
environment gets retrieved (maybe)
Likewise, after your main exits, a few more things have to happen:
Anything set up with atexit gets run
Your static objects get destroyed
cin/cout/cerr/clog get destroyed
all open output streams get flushed and closed
all open input streams get closed
Depending on the platform, there may be a few more things as well, such as setting up some default exception handlers (for either C++ exceptions, some platform-specific exceptions, or both).
Note that most of this is fixed code that gets linked into essentially every program, regardless of what it does or doesn't contain. In theory, they can use some tricks (e.g., "weak externals") to avoid linking in some of this code when it isn't needed, but most of what's above is used so close to universally (and the code to handle it is sufficiently trivial) that it's pretty rare to bother going to any work to eliminate this little bit of code, even when it's not going to be used (like your case, where nothing gets used at all).
Note that what you've shown is startup/shutdown code though. It's linked into your program, traditionally from a file named something like crt0 (along with, perhaps, some additional files).
If you look through your file for the code generated for main itself, you'll probably find that it's a lot shorter--possibly as short and simple as just ret. It may be so tiny that you missed the fact that it's there at all though.
This call 0x401318 <main>
is what you code resolved to, basically. main() is a function and there is code surrounding it, often called something like __start and __end.
What you see amounts, in part, to the CRT support code in __start, and cleanup afterward in __end.
GDB's disassemble command is nice for short C identifiers, e.g. main. For long, mangled C++ identifiers the verbosity is overkill. For example, using icpc I see results like
(gdb) disassemble 0x49de2f 0x49de5b
Dump of assembler code from 0x49de2f to 0x49de5b:
0x000000000049de2f <_ZN5pecos8suzerain16fftw_multi_array6detail18c2c_buffer_processIPA2_dPKSt7complexIdEilNS2_26complex_copy_differentiateIS4_EEEEvT_T1_T2_T0_SD_SE_RKT3_+167>: mov 0x18(%rsp),%rsi
Displays that long are annoying in the CLI. They make GDB's TUI assembly display all but useless.
Is there a way to tell GDB to show a truncated identifier? Say clip all but 50 characters?
Current GDB from CVS behaves the way you want when it knows that there is only one function in the disassembly:
(gdb) disas 0x000000000040071c
Dump of assembler code for function _ZNKSt8_Rb_treeIPiSt4pairIKS0_S0_ESt10_Select1stIS3_ESt4lessIS0_ESaIS3_EE21_M_get_Node_allocatorEv:
0x000000000040071c <+0>: push %rbp
0x000000000040071d <+1>: mov %rsp,%rbp
0x0000000000400720 <+4>: mov %rdi,-0x8(%rbp)
0x0000000000400724 <+8>: mov -0x8(%rbp),%rax
0x0000000000400728 <+12>: leaveq
0x0000000000400729 <+13>: retq
End of assembler dump.
When GDB can't know whether or not disassembly will cross function boundary, it still prints the "long" form:
(gdb) disas 0x000000000040071c 0x000000000040071c+1
Dump of assembler code from 0x40071c to 0x40071d:
0x000000000040071c <_ZNKSt8_Rb_treeIPiSt4pairIKS0_S0_ESt10_Select1stIS3_ESt4lessIS0_ESaIS3_EE21_M_get_Node_allocatorEv+0>: push %rbp
End of assembler dump.
Here is the patch which introduced the "short form".
This doesn't really answer your question, but you might be able to at least demangle things to make them a little less ugly:
set print asm-demangle on