how to read esp with gdb - debugging

0x0804889a <+361>: mov %eax,0xc(%esp)
0x0804889e <+365>: movl $0x2b,0x8(%esp)
0x080488a6 <+373>: movl $0x1,0x4(%esp)
0x080488ae <+381>: movl $0x8048ab0,(%esp)
program is adding data to %esp (the last line is a string from memory that i can probe)
i'm currently breaking at the last line of the above. and info registers shows
esp 0xffffd704 0xffffd704
when i try to display it i get
$esp = (void *) 0xffffd704
if i try to dump it
(gdb) dump memory mem2 0xffffd704 0xffffffff
Cannot access memory at address 0xffffd704
(gdb) info mem
Using user-defined memory regions.
There are no memory regions defined.
how can i see the full value of esp?

The error message is misleading. According to my tests, gdb prints that if any byte in the range is inaccessible. As such, the problem is with the end address. You can get the stack top from /proc/<pid>/maps, for example for my test program I got:
$ grep stack /proc/8277/maps
fffdd000-ffffe000 rw-p 00000000 00:00 0 [stack]
gdb is able to dump that memory range without problems.
Of course if you only want to read particular values of interest, you can use the x (examine) command.

Related

Very strange SIGQUIT when try to switch from ring 0 to ring 3

I am working on enabling Intel SGX on a unikernel that does not have a native ring 3 support. Hence in order to invoke the user-mode SGX instruction I need to implement a ring switch routine. I followed the JamesM's tutorial( 10.-User Mode (jamesmolloy.co.uk) , which is a 32-bit solution) to drafted a long-mode version:
void switch_to_ring3()
{
asm volatile(" \
mov $0x23, %rax; \
mov %rax, %ds; \
mov %rax, %es; \
mov %rsp, %rax; \
push $0x23; \
push %rax; \
pushf; \
push $0x1B; \
push $1f; \
iretq; \
1: \
");
return;
}
I am sure that I have set up GDT entries properly and 0x23/0x1B is exactly the indexes of user-mode code/data descriptors, in which the code descriptor value is 0xaffb000000ffff and the data descriptor value is 0xaff3000000ffff.
What's strange is that the iretq can be executed successfully, and the rip register could go to the next instruction of the iretq, which is a nop if I disabled the optimization and a ret if I enabled the optimization. However, when executing the next instruction, it will die without any output (my unikernel has an exception handler, even if for unhandled exceptions, it will output something). I try to use GDB to debug and GDB said that the program received SIGQUIT.
I checked the registers but find nothing wrong, cs is 0x1b, ss, ds and es are 0x23, and rip points correctly to the next instruction of iretq.
I am really confused about why it receives SIGQUIT. If some exception happened, it should output the dump message, or at least qemu log will track some 'check_exception' message, but the log is empty. Everything seems okay, correct segment registers, correct rsp/rbp/rip, the kernel code segment is user-accessible by setting the conformed bit of its descriptor, and the high/low base address in all descriptors are pointed to 0x0.
Being trapped in this problem for a whole day but cannot find any solution. I hope someone here could save my life T_T
I finally fixed it by setting U/S bit for all kernel code/data pages. Thanks for all of your comments #prl #PeterCordes !

Value can't be converted to integer while debugging with gdb

I am trying to debug assembler code with gdb in ubuntu x64 command line.
A disassemble command shows the following
0x0000000000401247 <+10>: mov %r12,-0x8(%rsp)
=> 0x000000000040124c <+15>: sub $0x18,%rsp
0x0000000000401250 <+19>: mov %rdi,%rbx
and after stepi command I want to explore the memory with address $0x18 to check the result of command.
I am using the following command x $0x18 and getting error Value can't be converted to integer.
And after trying the command x 0x18 it gives Cannot access memory at address 0x18 error.
How can I check the result of command in memory with address 0x18?
I want to explore the memory with address $0x18
There is no memory at address 0x18. The assembly instruction you are looking at: sub $0x18,%rsp subtracts a constant 0x18 from previous value of the RSP register (that's what $ in front of 0x18 means).

How to send EOF from command prompt *without newline*?

Sure, to send EOF from command prompt, Enter followed by Ctrl-Z does the trick.
C:\> type con > file.txt
line1
line2
^Z
This works, and file.txt contains line1\r\nline2\r\n. But how can you do the same without the last newline, so that file.txt contains line1\r\nline2?
In Linux, the solution is to hit Ctrl-D twice1. But what is the equivalent on Windows? Command prompt will happily print ^Zs at the end of a line without doing sending EOF. (And if you press Enter, then any ^Zs you typed get written to the file as literal escape characters!)
If there is no way to do this on Windows, then why?
1 https://askubuntu.com/questions/118548/how-do-i-end-standard-input-without-a-newline-character
The command type con > file.txt doesn't have any special handling for ^Z in the cmd shell, since the target file isn't con and the type command wasn't run in Unicode (UTF-16LE) output mode. In this case, the only ^Z handling is in the ReadFile call itself, which for a console input buffer has an undocumented behavior to return 0 bytes read if a line starts with ^Z.
Let's examine this with a debugger attached, noting that the number of bytes read (lpNumberOfBytesRead) is the 4th argument (register r9 in x64), which is returned by reference as an output parameter.
C:\Temp>type con > file.txt
Breakpoint 1 hit
KERNELBASE!ReadFile:
00007ffc`fb573cc0 48895c2410 mov qword ptr [rsp+10h],rbx
ss:00000068`c5d1dfa8=000001e3000001e7
0:000> r r9
r9=00000068c5d1dfd0
0:000> pt
line1
KERNELBASE!ReadFile+0xa9:
00007ffc`fb573d69 c3 ret
0:000> dd 68c5d1dfd0 l1
00000068`c5d1dfd0 00000007
As you see above, reading "line1\r\n" is 7 characters, as expected. Next let's enter "\x1aline2\r\n" and see how many bytes ReadFile reportedly reads:
0:000> g
Breakpoint 1 hit
KERNELBASE!ReadFile:
00007ffc`fb573cc0 48895c2410 mov qword ptr [rsp+10h],rbx
ss:00000068`c5d1dfa8=0000000000000000
0:000> r r9
r9=00000068c5d1dfd0
0:000> pt
^Zline2
KERNELBASE!ReadFile+0xa9:
00007ffc`fb573d69 c3 ret
0:000> dd 68c5d1dfd0 l1
00000068`c5d1dfd0 00000000
As you see above, this time it reads 0 bytes, i.e. EOF. Everything typed after ^Z was simply ignored.
However, what you want instead is to get this behavior in general, wherever ^Z appears in the input buffer. type will do this for you, but only if it's executed in Unicode mode, i.e. cmd /u /c type con > file.txt. In this case cmd does have special handling to scan the input for ^Z. But I bet you don't want a UTF-16LE file, especially since cmd doesn't write a BOM to allow editors to detect the UTF encoding.
You're in luck, because it happens that copy con file.txt does exactly what you want. Internally it calls cmd!ZScanA to scan each line for a ^Z character. We can see this in action back in the debugger, but this time we're in completely undocumented territory. On inspection, it appears that this function's 3rd parameter (register r8 in x64) is the number of bytes read as an in-out argument.
Let's begin again by entering the 7 character string "line1\r\n":
C:\Temp>copy con file.txt
line1
Breakpoint 0 hit
cmd!ZScanA:
00007ff7`cf4c26d0 48895c2408 mov qword ptr [rsp+8],rbx
ss:00000068`c5d1e9d0=0000000000000000
0:000> r r8; dd #r8 l1
r8=00000068c5d1ea64
00000068`c5d1ea64 00000007
On output, the scanned length remains 7 characters:
0:000> pt
cmd!ZScanA+0x4f:
00007ff7`cf4c271f c3 ret
0:000> dd 68c5d1ea64 l1
00000068`c5d1ea64 00000007
0:000> g
Next enter the 23 (0x17) character string "line2\x1a Ignore this...\r\n":
line2^Z Ignore this...
Breakpoint 0 hit
cmd!ZScanA:
00007ff7`cf4c26d0 48895c2408 mov qword ptr [rsp+8],rbx
ss:00000068`c5d1e9d0=0000000000000000
0:000> r r8; dd #r8 l1
r8=00000068c5d1ea64
00000068`c5d1ea64 00000017
This time the scanned length is only the 5 characters that precede the ^Z:
0:000> pt
cmd!ZScanA+0x4f:
00007ff7`cf4c271f c3 ret
0:000> dd 68c5d1ea64 l1
00000068`c5d1ea64 00000005
We expect file.txt to be 12 bytes, which it is:
C:\Temp>for %a in (file.txt) do #echo %~za
12
More generally, if a Windows console program wants to implement Ctrl+D handling that approximates the behavior of a Unix terminal, it can use the wide-character console function ReadConsoleW, passing a CONSOLE_READCONSOLE_CONTROL struct by reference as pInputControl. This struct's dwCtrlWakeupMask field is a bit mask that sets which control characters will immediately terminate the read. For example, bit 4 enables Ctrl+D. I wrote a simple test program that demonstrates this case:
C:\Temp>.\test
Enter some text: line1
You entered: line1\x04
You can't see this in the above example, but this read was immediately terminated by pressing Ctrl+D, without even pressing enter. The ^D control character (i.e. '\x04') remains in the input buffer, which is useful in case you want different behavior for multiple control characters.

Remove address from instruction disassembled via dbgeng's DisassembleWide()

I am disassembling instructions by passing their offset to DisassembleWide() function while writing an extension for Windbg. However, with the disassembled instruction, it adds the address of the instruction + hex opcode for that instruction.
I was able to remove the opcode by specifying DEBUG_ASMOPT_NO_CODE_BYTES flag in SetAssemblyOptions(). However I can't seem to get rid of the instruction offset. Neither DEBUG_ASMOPT_DEFAULT | DEBUG_ASMOPT_NO_CODE_BYTES, nor (DEBUG_ASMOPT_DEFAULT | DEBUG_ASMOPT_NO_CODE_BYTES) & ~DEBUG_ASMOPT_VERBOSE seem to work.
Am I missing something? Is there a way I can cleanly remove the offset from the instruction, or will I have to do it the manual way?
no Address will always be printed you have to parse it out yourself
if you are on a windbg session you can achieve this with .shell and awk
0:000> .asm no_code_bytes
Assembly options: no_code_bytes
0:000> .shell -ci "u #eip l4" awk "{$1=\"\";print $0}"
int 3
ret
mov edi,edi
int 3
.shell: Process exited

Why don't you get full stack traces when enabling the user mode stack trace?

I'm troubleshooting some memory fragmentation problems and I've been trying to figure out why things are being allocated and who's ultimately doing the allocation. So I enabled usermode stack traces for the process (+UST flag in gflags) and got a dump. When I analyze the dump and use the !heap -p -a Some_Address. I see a stack trace, but it's definitly not a full trace. I usually only see 4-7 functions in to the trace and then it stops. No errors are reported in the stack, but unfortunately it doesn't have enough information. I checked a bunch of the allocations and they all seem to have this same problem. I thought it might be the size of the stack database, but I would have expected to lost entire entries instead of just loosing part of them. Is there something I can do to increase the total size of the viewable stack. Some examples are below of the stacks I'm seeing.
0:000> !heap -p -a 3cb49008
address 3cb49008 found in
_HEAP # 80000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
3cb49000 0fdd 0000 [07] 3cb49008 07ed0 - (busy)
Trace: 6b69
7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
776bcfce ole32!CRetailMalloc_Alloc+0x00000016
77d0404a oleaut32!APP_DATA::AllocCachedMem+0x0000004f
77d04341 oleaut32!SysAllocStringByteLen+0x0000003c
77d03f9b oleaut32!ErrStringCopyNoNull+0x00000016
77d0456f oleaut32!VariantCopy+0x0000007e
3ff1946 xxxx!_variant_t::_variant_t+0x00000016
0:000> !heap -p -a 2774cfc8
address 2774cfc8 found in
_HEAP # 3cc0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
2774cfc0 0008 0000 [17] 2774cfc8 00020 - (busy)
Trace: 7de8
7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
4f6ad17 xxxx!malloc+0x0000007a
0:000> !heap -p -a 3ca25e08
address 3ca25e08 found in
_HEAP # 80000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
3ca25e00 0007 0000 [07] 3ca25e08 00020 - (busy)
Trace: 8588
7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
776bcfce ole32!CRetailMalloc_Alloc+0x00000016
77d0404a oleaut32!APP_DATA::AllocCachedMem+0x0000004f
77d04341 oleaut32!SysAllocStringByteLen+0x0000003c
77d03f9b oleaut32!ErrStringCopyNoNull+0x00000016
77d0456f oleaut32!VariantCopy+0x0000007e
4f35abd xxxx!std::_Construct<_variant_t,_variant_t>+0x0000004d
On 32-bit Windows the system uses EBP chain to take a stack trace. You need to disable FPO optimization (/Oy-). On 64-bit Windows you will get a good stack trace even with optimization.

Resources