Notes on Lena151 Course
Basics
General
- Returns are in eax
- Parameters are pushed in reverse order
- ZF: zero flag means if the result of something is 0. Not SET -> jnz/jne taken, SET -> jz taken, cmp X, X -> SET se uguali. Else NOSET. It is done beacuse it discards the result test X, X -> se X è 0 SET. Else NOSET. It is done beacuse it discards the result
- RVA is a relative virtual address: a memory address without the imagebase. VA is complete value you can see in RAM
- Step/Animate over = CTRL+F8/F7
- F12 = stop animate
-
- = go backwards
- push
+ ret = jmp (magic jump) - Note on jumps: they can be short or long, short take 2 bytes long take more (5)
- use resource explorers
- When disassembling and changing things is always better to break at the start of the routine to see if that part of code is used in different way (that can mess up the flow of the program)
- If the file is packed, after unpacking there can be problems on resolving the resources. A solution is using a resource rebuilding utility
- Armadillo verifies for bp so put the bp on another place not the obvious one
- SFX: magic things that unpacks by itself the OEP
- Tracing: learn it
- A Win32 function that you call will always preserve the segment registers and the EBX, EDI, ESI, EBP, ESP and EIP registers. Conversely, ECX and EDX are considered scratch registers and are always undefined upon return from a Win32 function.
- Algo hiding: program sense that you are fucking with it so it hides calls to the registration
- attaching: put an infinite loop so you can attach
Registers
eax : accumulator ebx : base ecx : counter edx : data esi : source edi : destination ebp : base pointer. Used with offset to access stack esp : stack pointer. Last pushed element eip : instruction
FPU
finit (initialise the FPU) fld (load a variable onto the stack) fild (load a variable as an integer onto the stack) fldpi (load pi onto the stack) fxch (exchange ST1 and ST0) fadd (add ST0 to ST1 and pop the stack) fsub (subtract ST0 from ST1 and pop the fmul (multiply ST1 by ST0 and pop the stack) fdiv (divide ST1 by ST0 and pop the stack) fsin (set ST0 to the sin of ST0) fcos (set ST0 to the cos of ST0) ftan (set ST0 to the tan of ST0) fasin (set ST0 to the arcsin of ST0) facos (set ST0 to the arccos of ST0) fatan (set ST0 to the arctan of ST0) fst (store ST0 into a variable) fstp (store ST0 into a variable and pop the fist (store ST0 into an integer variable) fistp (store ST0 into an integer variable and pop the stack)
Interesting APIs
FindWindowA (31,37) ReadTimeDateStampCounter
- GetModuleHandlerA = returns the imagebase
- DialogBoxes: DialogBoxParamA GetDlgItem GetDlgItemInt GetDlgItemTextA GetWindowTextA GetWindowWord
- MessageBoxes: MessageBeep MessageBoxA MessageBoxExA SendMessageA SendDlgItemMessageA Registry Access: RegCreateKeyA RegDeleteKeyA RegQueryValueA RegQueryValueExA RegCloseKeyA RegOpenKeyA
- Reading/Writing files: ReadFile WriteFile CreateFileA CreateFileExA RegSetValueExA
- Reading data from INI file: GetPrivateProfileStringA GetPrivateProfileIntA WritePrivateProfileStringA WritePrivateProfileIntA
- Reading data (other) LoadStringA lstrcmpA MultiByteToWideChar WideCharToMultiByte wsprintfA
- Time And Date: GetFileTime GetLocalTime GetSystemTime GetSystemTimeAsFileTime SetTimer SystemTimeToFileTime
- Creating a NAG-window: CreateWindowExA ShowWindow UpdateWindow Find messageboxtext SetDlgItemTextA SetWindowTextA
- IAT Things LoadLibraryA GetProcAddress
Call Stack
List of calls done. The bottom calls are older. Useful to have a glimpse of the program flow.
You start at the top and find the first item that you can use to find the code section you are interested in. If that one doesn’t work, you go further down the list, checking each function call until we get ‘back’ in the code far enough to find our compare/jump that determines if this function is called or not
Process Stack
- Grows high to low. From EBP (higher) to ESP (lower)
PE Header
Contains everything to get started with reversing a live program. Starts at imagebase and is 1000 bytes
SEH
Try catch management, windows style. Can be annoying but also be used to find OEP. I can let the debugger handle them
- all exceptions under olly’s options except kernel are unchecked to perform handling by user. (And pressing Shift-F7-8-9 instead of run).
- Forcing an exception -> INT 2D
Windows Messages
How it works
- Provide a window with settings, bitmaps, menu items etc
- Provide a loop (WinMain)
- Provide a callback (WndProc or DlgProc usually): this points to a usually big switch statement (aka if/else jumps)
- messages not handled by callback are handled by windows
- Messages are also used to display the window
Anti Debugging
Debuggers are divided in linear sweep and recursive traversal Techniques: 1. Obfuscation 2. Polymorphism and Self-modifying code 3. Debug Attachment Checking
IsDebuggerPresent Direct PEB Check -> The PEB is a section of code reserved with every process running on the system, setup and initialized by the Windows loader CreateToolhelp32Snapshot Name checking -> check on the name of the program OutputDebugStringA ReadTimeDateStampCounter, GetTickCount RDTSC ZwQueryInformationProcess ZwSetInformationThread Check for software bp (0xCC)
Opaque Predicates: fake branches Spaghetti code Table Interpretation: loading an array and jumping from that and not directly Checking char against char in common strings Return Obfuscation Magic jump (push return trick) Manual Import Loading: GetProcAddress and LoadLibrary to late load things The Trap Flag: setting a flag in an exception (be careful of pushad and popad ) Checksums
Metamorphic, Polymorphic and Self Modifying Code
Obviously for self modifying code the code section has to be modifiable
Stolen Bytes
Stolen bytes are bytes taken from the original exe, but placed in the packer code (usually when dumping you don’t dump the packer code because it is not run). Also, packer might move around things so even when dumping everything you are not sure of having the correct things
Inline Patching
Code Injection: inject code in a RUNNING application through LOADERS Inline Patching: inject code in a NOT RUNNING application Code Cave: area of memeory that is empty and where we can put our injected code
- I can also add an entire section to the binary and set it to executable to create a new big code cave
Unpacking
Ways: 1. Tracing (stepping) 2. Finding the change to ESP register (HW breakpoint): the packer saves the OEP in ESP. I BP HW there and hope than when I pop I’m in the real code 3. Exceptions of the compressors 4. Automatic
- The header contains generally empty space, packers like MEW use it for inline patching of their packing stub
- Packers can fuck with the header
- Packers do CRC checks so be careful when dumping. 1) Find it normally 2) Break on CreateFileA (35)
- VirtualProtect anti dump
Virtual Protect
VirtualProtect is used to change the permissions of code sections. Highly used with obfuscated or metamorphic code
Patchers & Loaders
- Patcher: Application that patches an executable. Basically used because shipping the patcher is easier than shipping the whole patched software
- Loader: Application that starts a process and waits for the process to unpack/deprotect itself. It then patches the process in memory to fix any bugs that the author left in the program
- Armadillo Sensing: Armadillo knows that you are tampering with it, so it changes the place in which he patches -> solution? patch both
Patching methods
- Stupid: fix a single jump
- Intermediate: fix some deep jumps
- Advanced: fix the place where the decision is done
Type of BP
Software (INT3) -> Change an opcode. Can be identified by program Hardware (INT1) -> Only 4, they use registers Memory (INT2) -> Only 1, slows a lot (debugger has to watch the whole block)
Area Searching
- Go through the program with F8 and identify the problematic call, the go there and do F7
- Write down jumps. In general you have to have experience to see at first glance what is happening
- Alt f9 drop: run until code (exit function or module)
- To investigate the part where a program is waiting input, a good way is pressing F12 to pause and then trace
- The check for jumps is always done on a pointer, so let’s see what sets that pointer: How to find the pointer? HW BP or MEM BP on the pointed byte, Finding the references to the pointer
- Be careful for repeated checks on a pointer
- Text search
- use “referenced by”
- First, when I arrive in a place I want to be visited, I search for the start of the function that will probably arrive there -> check for the closest “ret” above. Try to find start and finish of routines (IDA might help). “PUSH EBP” is a routine start
- Have a list of API where to break
- Call stack
- F12 = pause
- Alt+F9 = exectute until usercode
- pause drop after messagebox -> Alt F9
- String search, but also Unicode. Strings will not be decrypted until they need to be used. You can also search for names of location (of registry key for example)
- Point-H method (to find key routine): Ricardo Narvaja
IAT Searching & Rebuilding
- imagebase (usually 400000)+3C+80h = Place in the header where IAT info is located (fa 140)
- FF25 method to find IAT
- search dll names
- Entries start with high values like 77
- Redirection
- Structure
- How it identifies the end of the IAT: remember the dwords at 0 are just separators.
- IMPORT_IMAGE_DIRECTORY: puntata dalla posizione precedentemente descritta nell’header. Contiene tanti IMAGE_IMPORT_DESCRIPTOR quante dll importate più una settata a vuota
- IMAGE_IMPORT_DESCRIPTOR: OriginalFirstThunk DWORD (important): backup, punta ad una zona sotto TimeDateStamp DWORD: inutile usually 0 ForwarderChain DWORD: inutile usually 0 Name DWORD (important): punta al nome del dll FirstThunk (important) [array of pointers to be overwritten] => IAT (di solito sopra)
- The “overwriting” can be in a form of direct address, jump to address or push address
- Redirection: DLL functions are made to point to packer code, do some magic and then go where they should
- a program needs only two API’s to be able to “grab” all imports in an executable
- Authors can put fake thunks, remove them
- search for kernel32.dll (always present)
- importing an API from a dll that imports that API in its turn from a windows dll confuses ImpRec.
OEP Searching
- backtracking (34)
- Exception (24): are managed by program normally but debugger intercept them. Shift-F9 to pass the exception to the program. Return exceptions untill you have the running program, then do it again but one less time -> bp on section (F2 or mem bp) on code section and ci siamo
- (bp CreateThread, shift F9 to create bp?)
- oep is in usercode so search for when the module changes
- have a list of common oep structures for each compiler
Keygen
Keygen: generate key Key fishing: finding the correct key
- hmemcpy
TLS
Code can be put into this TLS section and can be run. The interesting thing about this is that the TLS code will run BEFORE the main entry point of the binary is run. When the Windows loader first loads the binary into memory, right after it loads in the DLLs needed, it checks a location in the PE header to see if there is a TLS section set up, and if there is, it looks for a callback address. If one is provided, this address is called, and the code in this section is run. After this runs, the loader then hands control over to the main application
- Usually it’s not used unless it is an antidebugging technique or Delphi exe
- DLLs can have TLS callbacks
- TLS callbacks can create other TLS callbacks
Packer List
CrypKeySDK5.7 EZIP1.0 eXPressor1.3 MEW1.1 NsPack3.5 Noname Exe32Pack1.42 The Fusion 4.0 Armadillo v4.0 tElock 0.98b1 Aspack Asprotect SKE 2.1x Yoda’s Protector PEC+MSLRH 0.32a PECompact
Appendix
Resource Hacker
You can identify the resource inside a PE file using resource hacker. It gives you an ID (or a name) and you can use that
Techniques if the code looks fucked up
The problem is that the debugger is seeing code as data and data as code. There are 2 solutions
- Select the area to reinterpret and make it analysis as data/code
- Put a nop instead of the junk
—Waaaaaa
Finding Things In PE file by using Memory
- Find the section in which the RVA is -> Iterate through section table (Note: sections are contiguous in memory)
- I’ll get an offset. Add that to the base address of the section
Offset = VA - Imagebase - Virtual Offset* + Raw Offset* (for exe on disk) VA = Offset + Imagebase + Virtual Offset* - Raw Offset* (for exe on memory) RVA = VA - Imagebase * = see section table
Lena 34 oep finder tech Lena 35 some anti re tech list
different styles. Lena just search for jumps, R4ndom uses callbacks