I have my windbg all set with srcpath and all.
I have added a breakpoint at one function and I can see the stack trace. When the breakpoint hits, the windbg shows the source code at current instruction with no problems. But I would like to see the source code at some other address. How can one see the sourcecode at given address like we can with disassembly We use "u "?
What command is for viewing source code? Thanks
.open -a is your friend. If you have yor symbols set up correctly, it will open the source that contains the code at the specified address.
If You have the source code of debugging code why would You like to browse/view it from windbg? Source mode makes debugging very simple but windbg is not a "code browser".
If You want to see the source code at the given address simply check what function "covers" this address e.g.:
kd> uf fffff800`02be05d0
nt!NtOpenFile:
fffff800`02be05b0 4c8bdc mov r11,rsp
...
fffff800`02be05d0 458953e0 mov dword ptr [r11-20h],r10d
Then ctrl-o and open your source code that contains this function(your func ofc unless You work for microsoft :D) and browse it in windbg.
Related
I am just starting to learn Assembly (x86 NASM) and I am currently going over function calls. Wherever I looked on the internet I saw everyone calling functions like this:
call power
Where power is the label where the function starts. But what I am trying to see is how to print something in Assembly, and interestingly enough, calling a function like in the above case doesn't seem to work. We'll use the printf function from C. Say I already used extern printf and import printf msvcrt.dll in my program (so I can actually use printf), also say I already defined a symbol in my data segment msg db "Hello World", 0 and now I am trying to print this message. If I do this:
push dword msg
call printf
Nothing happens, it doesn't work. I have no idea why. However, if I do this:
push dword msg
call [printf]
The message is printed just as expected.
This doesn't make much sense to me after all the articles that I read used just the label, without brackets. It also made a lot of sense to me when using just the label as we're using the call instruction to perform a jump to that label, so we needed the address of the label. But here it doesn't make sense at all to me why we're using the brackets and what exactly happens. I mean, what is [printf] and what would [power] be, for the example I presented at the start of my question. However, despite my confusion, this is what works and the method I initially used doesn't work.
Can you please tell me exactly what is going on? (PS: I am using Olly Debugger if that makes any difference)
It depends on what is "printf" in your assembly. If it is a function pointer (aka, the address of some function is stored at the address named "printf"), then you need brackets []. If "printf" is a function, that is, if the machine code is stored at the address that your assembler calls "printf", then you must not put brackets (or else you will probably end up with a segmentation fault, as the first 32 of 64 bits of machine code of "printf" probably don't accidentally contain an address of an executable code).
gdb in msys, doesn't show the name of the function call. Next to the address of the function call I have normaly the name of the function like . Why it's not the case with this exe and how can I fix it? gdb console
Why it's not the case with this exe
Because GDB doesn't know what function address 0x4023d0 corresponds to.
how can I fix it?
Depending on what code resides at address 0x4023d0, and why GDB doesn't have a name associated with it, this may or may not be fixable. But there is not enough info for me to even begin guessing what code might be there.
I recently started learning assembly and was wondering if it is possible for us to have our own defined entry point for an assembly code when compiling with gcc?
For example the standard code that compiles with gcc is
global main
section .data
section .bss
section .text
main:
I would like to change the entry point to a more defined name such as "addition", something like this below.
global addition
section .data
section .bss
section .text
addition:
A reason for why im using gcc to compile in the first place as well is that im using c libraries in my assembly code for "printf" and "scanf", and everytime I tried to change the entry point, I would get an undefined reference to main error.
If you are writing in assembly and not using the C runtime library, then you can call your entry point whatever you want. You tell the linker what the name of the entry point is, using either the gcc command line option -Wl,--entry=<symbol> or the ENTRY directive in the linker script. The linker writes the address of this entry point in the executable file.
If you are using the C runtime library, then the entry point in the executable file needs to be the entry point of the C runtime library, so that it can perform initialization. This entry point is typically called crt0. When crt0 finishes initializing, it calls main, so in this case, you cannot change the name.
You can put multiple labels on the same address. So you can stick the main label at whatever place you want the CRT startup code to call.
global main
main:
addition:
lea eax, [rdi+rdi] ; return argc*2
ret
I checked, and GDB chooses to show main in the disassembly for the block of code following the label, regardless of which one you declare first. (`global addition doesn't help either.)
Of if you want to be able to change one line at the top of your file to select which function is the main entry point, you could maybe do
%define addition main
I'm not sure if NASM lets you create an alias or weak-alias for a symbol, like with GAS
.weakref main, addition. (Call a function in another object file without using PLT within a shared library?)
I've tried declaring variables in .text segment using e.g. file_handle: dd 0.
However, trying to store something in this variable like mov [file_handle], eax results in a write error.
I know, I could declare writeable variables in the .data segment, but to make the code more compact I'd like to try it as above.
Is the only possibility to use the stack for storing these value (e.g. the file handle), or could I somehow write to my variable above?
Executable code segments are not writable by default. This is a basic security precaution. No, it's not a good idea. But if you insist, as this is a toy project anyway, go ahead.
You can make yours writable by letting the linker know to mark it so, e.g. give the following argument to the MS linker:
link /SECTION:.text,EWR ....
You can actually arrange for the text segment of your Windows process to be mapped read+write+execute, see #Kuba's answer. This might also be possible on Linux with ELF binaries; I think ELF has similar flags for segments.
I think you could also call a Windows function (VirtualProtect) to change the mapping of your text segment to read+write+execute from inside your process.
Overall this sounds like a terrible idea, and you should definitely keep temporaries on the stack like a C compiler would, if you want to avoid having a data page.
Static storage for things you only use in part of the program is wasteful.
No it's not possible to have writable "variable" in .text section of an assembly program.
When writing file_handle: dd 0 in the .text section and then assemblying, your label file_handle refers to an address located in the text section of your binary. However the text section is read-only.
If the text section wasn't only read-only accessible, a program could modify itself while executing.
Currently, I'm running GDB with the set disassemble-next-line on setting. For each line, this gives me a format that looks like:
0x08120921 <arith_driver+1>: 57 push %edi
Instead, I'd like the line to look like:
0x8120921<arith_driver+1>data.c:2577 push %edi M[0xffffc9c4]=0x084073c2 esp=0xffffc9c4
where M[address] represents a location in memory and esp refers to the register. Everything else is fairly self-explanatory. It seems like there should be a way to specify assembly code output format, but I can't find anything. Any help?
There's no built-in way to do this. You can maybe do some of it by modifying the gdb source code.