I am new to assembly language, and I am using macOS. The book I read uses DOS's debug instruction, which could see the values in registers at any time without set breakpoints in some executable programs like lldb, and could execute basic assemble instructions like mov ax, 2000. I know that macOS runs on a x86_64 machine, which is different from DOS. I simply want a way that can inspect and interact with registers/memory in terminal without an formal assembly program.(For example, in DOS, type in debug -r and I can see all the values stored in registers).
In lldb - the stock MacOS debugger
register read
will show you all register values
Also possible with shortened syntax for quicker typing
re r
If you want the floating point registers (xmm* for x86-64) too included
re r --all
If you want particular register value
re r rax
lldb is used in current versions of Xcode the MacOS free programming IDE from Apple which allows you to target MacOS & iOS.
You can also go with the terminal route when you would run your program with:
lldb ./yourProgram
But this approach will require a lot of typing and knowledge about your binary, so I don't recommend it for starters.
Related
I've got a Windows application with a GUI written in Rust and winapi. Despite its GUI, it behaves like a console application. When the exe file is started, a Command Prompt window pops up, and the application is run from it. This is not what I want; a main window should open instead, as in all real desktop apps. How can I achieve this goal in Rust with winapi?
I've investigated some options. You can develop Windows desktop applications using Tauri or gtk-rs, but both of these techniques have drawbacks when used for Windows apps. More options may be found here. I've also tried the windows-rs samples available on the internet, but they're all console apps with a graphical user interface, which isn't what I'm looking for.
I also note that C++ desktop applications use the function int APIENTRY wWinMain(...) as the entry point while console applications use int main(...), and wWinMain doesn't seem available in rust winapi.
Whether the system allocates a console for a newly created process is controlled by the Subsystem field in the Windows-specific optional PE header. The field is populated through the linker's /SUBSYSTEM command line option. The only relevant arguments for desktop applications are CONSOLE and WINDOWS. The former instructs the system to allocate a console on launch, whereas the latter won't.
You can instruct the linker to target the WINDOWS subsystem from Rust code by placing the per-module
#![windows_subsystem = "windows"]
attribute (see windows-subsystem) inside the main module of your application.
You'll find an example of this in the core_app sample of the windows crate.
This is the most convenient way to target the WINDOWS subsystem. You can also explicitly pass the linker flag along, e.g. by placing the following override into .cargo/config.toml:
[build]
rustflags = [
"-C", "link-arg=/SUBSYSTEM:WINDOWS",
]
This may or may not work, depending on the linker you happen to be using. Since the linker isn't part of the Rust toolchain, making sure that this works and has the intended effect is on you.
A note on the entry point's function name: It is irrelevant as far as the OS loader is concerned. It never even makes it into the final executable image anyway. The PE image only stores the (image-base-relative) AddressOfEntryPoint, and that symbol could have been named anything.
The concrete name is only relevant to the build tools involved in generating the respective linker input.
More info here: WinMain is just the conventional name for the Win32 process entry point. The underlying principles apply to Rust just the same, particularly the aspect that the user-defined entry point (fn main()) isn't actually the executable's entry point.
I am trying to write a simple OS, I already wrote a bootloader but now I want to debug it, so I switched from using VirtualBox to QEMU because I saw it had better debugging.
The problem is that after I added the -s parameter to QEMU command and successfully connected via GDB, it says that the symbol table isn't loaded and that I should use the "file" command.
The only difference from what I did to what I saw people on the Internet do, is that they started GDB with gdb vmlinux, but I can't do that because I am not debugging a Linux kernel... so I figured that the issue is that I didn't start GDB with an executable, but using the "file" command on my OS image, and the compiled and linked .out file, tells me it's a "DOS/MBR boot sector", so I can't start GDB with either of them (I tried to do that anyways, but GDB failed).
Help would be appreciated.
EDIT: also, I did assemble the bootloader with the -g and --gstabs+ options.
gdb would like a file so that it can give you symbolic debugging information. For that you will need to give it a file in a format with debug info which corresponds to where your OS ends up in RAM. The "DOS/MBR boot sector" file is a disk image (the BIOS will load part of this into RAM for you, and it will then presumably finish loading code itself).
But gdb will also entirely happily let you do assembly-level debugging; you can just ignore the warning about not having a symbol table, and use the single step instruction, disassemble-from-pc and similar commands:
"disas $pc,+32" disassembles 32 bytes from the current PC
the display command prints after execution stops, so "disp /3i $pc" will print the next 3 instructions every time gdb gets control
"stepi" and "nexti" do single-instruction step/next ("step" and "next" are source-line stepping and require debug info)
I am doing some OSX kernel debugging with lldb and KDK.
When the kernel crash,I want to view the zones,and search the zones.
So I use:
(lldb) command script import lldb.macosx.heap
(lldb) cstr_refs CSTRING
This command is always working in Ring3 debugging, but when at kernel debugging, lldb give me an error:
error: error: use of undeclared identifier 'malloc_get_all_zones'
error: 1 errors parsing expression
The script heap.py is unusable in kernel?
How to search the kernel zones at this situation?
Someone more familiar with kernel issues can maybe tell you how to get the information you want out of the kernel. I can answer the part about "heap.py". It is only meant to be used when debugging userland programs. It relies on details of the userland malloc implementation, and it relies on being able to call functions in the debugee which is not currently possible when debugging the kernel.
Note, if you get the KDK so you have the dSYM for the mach kernel, it defines a bunch of commands that poke around in the kernel's data structures. It may be one of them will tell you what you want to know. Remember to run the lldb command:
(lldb) settings set target.load-script-from-symbol-file true
in order to allow lldb to read in the Python from the dSYM that defines all these macros. Then running the lldb help command will show you all the kernel-specific commands.
People,
I have just working on OSX 10.9, and have a crash at hand to debug.
I see OSX has LLVM and LLDB which replaces well known and well documented gdb.
Anyway, I see in crashreport the precise stack trace, and that's pretty impressive from Apple.
However, I can get to image lookup in lldb and print the API name.
When I use verbose option with image lookup it prints few extra information, however, I am still not able to view local variables in the specific API.
I tried image dump, image sym-tab etc and other lldb options.
None of them seems to helping. Scanned through StackOverflow to see if its there's but not luck yet.
Therefore I have the Q
From OSX crashreports we cannot get stack-trace with local variables/arguments values?
How do we see a function arguments/locals variables using LLDB when we a OSX crashreport handy.
I see frame variable etc works fine when attaching to a running process, however these doesn't work when I crash the process and try to see the locals/arguments.
Request you to please guide.
THank you.
The CrashReporter output consists (mainly) of a backtrace of all the threads in the program, the list of libraries/frameworks that were loaded at the time (with their load addresses and Mach-O UUIDs to identify which build of each binary was being used) and the register context for the frame that crashed.
image lookup -va in lldb will show you where the arguments/variables were located at that given pc. If a variable is stored in register rbx at that point, image lookup will say it's in rbx. Often times a variable is stored on the stack and the location will say something like rbp-40 where rbp is the frame pointer register on x86_64. In that case, it means the variable is currently available on the stack at the value of rbp minus 40.
Crash reports do not include any of the stack contents -- they intentionally don't include things that might be sensitive. For instance, your program might have a password in plaintext in a stack local variable.
If a variable you're interested in is stored in a register at the point of the crash, you can use the register context section of the crash report to figure out what value was in there.
Often it's not quite that simple. If you can read your way through assembly language, the best way to figure out what really happened is to disassemble the crashed function and use the register context information to understand why the final instruction resulted in the crash.
I am trying to learn assembly language in my spare time to help me in my role as a developer using high level languages.
I have followed the NASM tutorial here: http://leto.net/writing/nasm.php.
I am able to create and run a simple program that prints HelloWorld to the screen. I am confused by the following paragraph in the link above:
mov eax,5 ; the syscall number for open()
So where do find out all of the semantics for all of the various system calls?
Well first, the numbers are listed in asm/unistd.h in Linux, and sys/syscall.h
in the *BSD's
I assume that this means that: if there is a 5 in the eax register, then it is a system call for open. Are the rest of the system calls documented somewhere?
I am using NASM on a Windows 7 PC.
List of Windows API calls
If and when you use NASM on Linux,
http://asm.sourceforge.net/syscall.html#1
http://syscalls.kernelgrok.com/