【 Preface 】 write this document when I met enough food, many problems, I would like to thank bkbll, SobeIt a1rsupply and pointing, TCH of hard work, only the birth of this document, this article there may be some errors, the error is due to my mistake, if you have any comments, welcome to http://www.itaq.org noted or E-mail: zf35@citiz.net 【 overview 】 implementation on the server to process created by the control has a great significance, by monitoring the process of creating, we can make the process of being allowed to run correctly, and it is not permitted by the program will create fails, this can prevent unknown Trojans, virus and worm threats on the server.
To achieve these purposes, you must create a process-related hookwindows API, under the insidethewindowsNT "and" NativeAPIReference records, plus the actual track, softIce windows create process API call procedures are as follows: 【 code 】 CreateProcessA-> CreateProcessW-> CreateProcessInternalW-> ... > end call-ZwCreateProcess this document we use CreateProcessW to achieve our goal, of course, you can also use other several API. This document demonstrates code is a little changes can be applied to arbitrary Ring3 function. For hook an API, you can use a lot of ways, this article use override function entry point approach to achieve hook CreateProcessW, more detailed information please refer to the windows SobeIt write down some way hookAPI. 【 Copy-on-write 】 initial test, I use the rewrite function aCreateProcessW softice is the entry point code, F5 to switch back to windows after the discovery of all things, but when I write a program to modify the entry point code CreateProcessW, your changes are only valid for this process, other processes for system did not produce any effect. Use softice track and found this process CreateProcessW virtual address is mapped to a new, and other process on a different physical address, if you read the Webcrazy copy-on-write mechanism ", it is not hard to see that this is the impact of copy-on-write mechanism. For the system DLLs, each DLL that is mapped to a different process on the same virtual address, these virtual address and point to the same physical address by which system the lowest resource consumption when a process tries to overwrite data in physical memory, in order not to affect other processes, the system automatically assigns a new physical memory, the original data in physical memory copy, overwrite, and then to overwrite memory of the process's virtual address remap it to a new physical memory, and other process or map in the original physical memory, this is the "copy-on-write technique" (copy-on-write), then the system is how to determine when you should use copy-on-write? this is a virtual address to determine, PTE when copy-on-write flag in the PTE is set, any of the virtual address of the write operation will cause a copy-on-writ 【 three viable 】 in order to achieve a global hook, we cannot be restricted by copy-on-write mechanism, now I thought of three approaches to achieving our aim. 1. through the driver to modify the page table entry (PTE) properties so that the corresponding virtual address CreateProcessW lost copy-on-write property, which in itself processes on CreateProcessW entry point code modifications will take effect for all processes in the system, enabling global hook. 2. through the windows themselves an object to the physical memory \\phymem for direct reading and writing, first positioning itself processes Eprocess (KTEB) (PS: how to navigate in Ring3 arbitrary process Eprocess please refer to the written before I get process Eprocess "), you can get after Eprocess process page catalog, and then use \\phymem read stored page catalog contents of physical memory, and then simulate operating system virtual address-> physical memory address conversion, the resulting CreateProcessW corresponding physical address, use \\phymem we avoid copy-on-write mechanism directly overwrite CreateProcessW. 3. through the most conventional means to achieve the objective, the first enumeration system all processes and then by VirtualAllocEx, VirtualProtectEx VirtualQueryEx, etc functions modify each process page properties, allocate new space. Finally our code using WriteProcessMemory wrote all process space, the use of override CreateProcessW entrance to Jmp * ** * ** * to go to our code, change the function of the flow of execution. The above three methods, method 1 is only a concept, not a reality, drop, I go back and try the page Welcome to master to achieve, and then mail a copy of the code give me: P method 2 I wrote a complete code to implement it, but in this documentNot for discussion, the document will become very long, I will be in a separate document specifically describes the approach of specific implementation. Method 3 so that the focus of this article, the following is a detailed description of the method 3. Query the base address and CreateProcessW properties here we use the function, its VirtualQueryEx prototype is as follows: SIZE_T VirtualQueryEx (HANDLEhProcess, LPCVOIDlpAddress, PMEMORY_BASIC_INFORMATIONlpBufer, SIZE_TdwLengt); Parameter description: HANDLEhProcess want to query the memory information on the process handle LPCVOIDlpAddress point to a memory area you want to query the pointer PMEMORY_BASIC_INFORMATIONlpBuffer MEMORY_BASIC_INFORMATION structure pointer points to SIZE_TdwLengthlpBuffer size after you call this function, related information is stored in the structure pointed to by lpBuffer is modified in the page properties for CreateProcessW a page that has the following properties: PAGE_EXECUTE PAGE_EXECUTE_READ PAGE_EXECUTE_READWRITE PAGE_EXECUTE_WRITECOPY PAGE_NOACCESS PAGE_READONLY PAGE_READWRITE PAGE_WRITECOPY we modify by VirtualProtectEx page properties: BOOL VirtualProtectEx (HANDLEhProcess, LPVOIDlpAddress, SIZE_TdwSize, DWORDflNewProtect, PDWORDlpflOldProtect); Parameter description: HANDLEhProce ss process handle LPVOIDlpAddress point to want to modify a pointer to the memory region SIZE_TdwSize modify the size of the memory area DWORDflNewProtect new page attributes PDWORDlpflOldProtect links to save the old page property of memory from the back of the code we can see that in order to overwrite the function entry point code, we must give it PAGE_EXECUTE_READWRITE property. In the process of allocating free space optical modify function entry point code is not enough. We must have written some code to take over the work, as CreateProcessW process space is isolated, in order to achieve the goal of a global hook, we must provide each process for a piece of space to store our code, this is going to use this function, VirtualAllocEx VirtualAllocEx prototype is as follows: LPVOID VirtualAllocEx (HANDLEhProcess, LPVOIDlpAddress, SIZE_TdwSize, DWORDflAllocationType, DWORDflProtect); Parameter description: HANDLEhProcess process handle LPVOIDlpAddress points to a pointer to the allocated memory area SIZE_TdwSize assigned area DWORDflAllocationType memory type DWORDflProtect new memory properties we use WriteProcessMemory function to write to the remote process's code and data, the prototype is as follows: BOOL WriteProcessMemory (HANDLEhProcess, LPVOIDlpBaseAddress, LPCVOIDlpBufer, SIZE_TnSize, SIZE_T * lpNumberOfBytesWritten); Parameter description: HANDLEhProcess process handle LPVOIDlpBaseAddress point to write address pointer LPCVOIDlpBuffer point to write the data pointer size of SIZE_T * SIZE_TnSizelpBuffer lpNumberOfBytesWritten actual number of bytes written for the magic in my compiler using WriteProcessMemory put myself to write a function JmpToAddress writes the contents of the remote process space, regardless of my JmpToAddress content is written to the space are E9 ** ** the few bytes, which made me very confused, from machine code, this is a relative jump instruction. It is come from it, in order to understand this problem, I used the VC Debug it, enter in the watch window, showing JmpToAddress JmpToAddress virtual address 0x00410XXX, and then open the memory window to view the memory storage of content, discovery is JmpToAddress code, this is strange, mysterious E9 * *** fromWhat to do, so I ask the a1rsupply, he told me that the debug version of the VC will generate a jump table, light, original play of magic is a compiler. In order to remote processes properly written code, we must calculate the real function address, the following I wrote a piece of code to calculate the real function address: __asm {pusad leaeax, JmpToAddress movecx, JmpToAddress shrecx, 8 addeax addeax, ecx, eax, 5 movJmpAfterCalc popad} solve trouble-positioning problem in writing the code, I encountered another big question is how to locate the address. I write JmpToAddress () function as follows: JmpToAddress void__declspec (naked) (void) {__a smjmp [HookedAddr]} in the local process this code no problem, but when it is written to the remote process problems will arise, we take a look at its assembly code, following jmp [00401Cxxx] we note this process in the virtual address is deposited in the HookedAddr address, but the remote process, this address points to is something else, jmp past will produce unexpected results, in order to achieve the correct behavior, we'll write to the remote process WriteProcessMemory HookedAddr content, and then use a relative address references it JmpAddress void__declspec (naked) (void) {__asmcalllag flag: __asmmovebx __asmpopeax __asmaddeax, 0x0e, [eax] __asmjmpebx} popeax, eax is deposited inside of this directive, the address of the virtual, plus a fixed value, [eax] is through WritePr
No comments:
Post a Comment