Hi everyone! This video covers...
• Create a Windows assembly .asm program using Microsoft Macro Assembler (MASM).
• Intro to Debugging Tools for Windows/WinDbg.
• Intro to Windows x64 shadow store (aka "shadow space").
• Examine stack/shadow store in both Visual Studio Debugger and WinDbg.
• How parameters beyond the 4th are passed on the stack.
• Overview of x64 zero-extending.
Tutorial source code:
git clone https://github.com/AshleyT3/tutorial-sample-code.git
Clickable Table of Contents
0:00:00 Start
0:00:15 Intro
0:04:26 ASM workflow
0:05:50 MASM in MSVC tools
0:06:58 Install Visual Studio, Install VSCode
0:08:28 Install Debugging Tools for Windows
0:12:11 WinDbg dir layout
0:14:30 Debug tools portable nature
0:17:08 WinDbg from command line
0:17:32 WinDbg Help
0:19:47 x64 build tools cmd line
0:20:09 assembler test run, MASM/ml64 help
0:20:28 .asm skeleton, Sections (code, data, const, etc.)
0:21:21 Everything is data?
0:25:16 Sections/EXE/OS Loader
0:25:43 Not off limits! (optional tangent)
0:28:32 .CODE, PROC/ENDP, END of ourprogram.asm
0:30:09 assembler command line to build.
0:31:56 Link switches /SUBSYSTEM, /ENTRY switch, Link online help.
0:34:48 Link /DEBUG switch, ml64 /Zi switch.
0:37:24 Assemble/Link ourprogram.asm to exe
0:37:55 Debug ourprogram.exe (WinDbg)
0:38:29 WinDbg workspace setup.
0:42:11 .reload ("reset" module/symbol info).
0:42:24 lm, x, and u commands (list modules, examine symbols, unassemble)
0:43:58 WinDbg tried and true.
0:45:31 Debugger engine (dbgeng.dll), Symbol "engine" (symsrv.dll).
0:48:48 bp command (set breakpoint). Debugger command line benefits.
0:51:16 setup symbol path/cache
0:54:15 debugger.chm (WinDbg Help pt2)
0:55:04 x (examine symbols pt2 w/symbols setup).
0:55:21 disassemble main. Go To address, diassembly window. Source window.
0:56:38 Updating workspace file.
0:56:51 Toggle breakpoint F9.
0:57:19 g "Go" command.
0:59:09 end of program, NtTerminate process
0:59:44 mov instruction, reg overview.
1:02:58 mov eax,123 (process exit code).
1:04:58 t "trace" command
1:06:07 $ debugger comments char.
1:06:24 r "register" command.
1:07:07 .asm decimal vs hex ('h' suffix and '0' prefix).
1:07:27 ? evaluate expression command
1:09:00 zero-extending overview. Zero-extending exit code.
1:16:57 ret instruction
1:17:44 x64 calling convention pt1. Calling convention in debugger help.
1:19:38 rcx 1st parm example
1:21:13 p "step over" command (F10)
1:21:38 NtTerminateProcess
1:22:16 verifying return exit code
1:23:07 stack shadow store & parameters.
1:27:01 shadow store, debug build
2:00:14 stadow store, release build
2:18:34 MessageBox C++ program (prep for .asm)
2:20:13 VS symbol setup. Disable "Just my code."
2:22:01 Stack calling kernel, waiting, Nt* APIs
2:23:06 Symbol load delays
2:24:25 MessageBox call setup, symbol lookup, memory/register windows
2:31:19 VS "step over." VS lookup/verify return value
2:34:01 MessageBox .asm program
2:34:18 includelib help linker find imports
2:35:07 Compile/Assemble/Link Overview: .asm/.cpp to .obj to .exe
2:38:20 EXTERNDEF: importing an API
2:39:09 includelib, EXTERNDEF recap
2:39:53 CONST SEGMENT: constant program data
2:40:19 db zero-terminated strings
2:41:17 .CODE & PROC revisited
2:41:48 .asm ';' comments
2:44:29 shadow store & 16-byte stack alignment
2:55:59 assemble/debug MessageBox .asm program
2:56:35 'r' command pt2
2:56:53 '@' to use a reg value in an expression
2:57:28 detecting 16-byte alignment, misalignment
2:57:53 hex recap
3:05:01 hex num ending in zero is 16-byte aligned
3:07:28 call's push & 16-byte alignment
3:08:32 simple caller/callee alignment example
3:13:25 16-byte alignment before "call"
3:14:49 typical alloc shadow & 16-byte align at once
3:18:36 observing 'rsp' not 16-byte aligned
3:19:24 calc alignment example.
3:20:58 alignment/allocation clues at a glance.
3:24:32 MessageBox call setup (asm).
3:24:57 'Enter' repeats WinDbg command.
3:25:23 'da' and 'db' to dump ASCII/bytes (WinDbg).
3:28:40 'g' to run MessageBox call.
3:29:13 epilogue stack restoration.
3:30:31 'dps' and 'dq' to dump stack.
3:32:12 'ret' pops stack to 'rip'.
3:35:42 .restart the program.
3:36:06 'ln' for reusable symbolic-based address, u command pt2
3:37:14 bp using 'ln' obtained address.
3:37:29 trace from kernel32 to main.
3:39:27 'call' pushes return address.
3:40:02 WinDbg up arrow history recall.
3:46:17 ourprogram.asm (skip here for very fast path).
3:49:47 'gu' Go Up (WinDbg)
3:50:26 not following ABI outcome.
3:52:10 assembler listings (.lst files).
3:57:29 Outro
Errata:
47:00 I say symsrv then dbgsrv, should all be symsrv.
Buy Me a Coffee
https://www.buymeacoffee.com/ricochettech
Subscribe to the the RicochetTech email list:
https://ricochettech.net/subscribe