USH2202H1 - Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution - Google Patents
Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution Download PDFInfo
- Publication number
- USH2202H1 USH2202H1 US10/835,712 US83571204A USH2202H US H2202 H1 USH2202 H1 US H2202H1 US 83571204 A US83571204 A US 83571204A US H2202 H USH2202 H US H2202H
- Authority
- US
- United States
- Prior art keywords
- thread
- prologue
- threads
- context
- hooking
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Abandoned
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/461—Saving or restoring of program or task context
Definitions
- the present invention relates to the protection of computer systems. More particularly, the present invention relates to hooking of runtime processes.
- a method of dynamically hooking runtime processes without interrupting the flow of execution includes: suspending a thread; hooking a function comprising modifying code of the function; and determining whether the thread was executing the modified code when the thread was suspended. If the thread was not executing the modified code, the thread is resumed. If the thread was executing the modified code, the context of the thread is changed to redirect the thread to a saved copy of the original prologue. In this manner, unpredictable behavior of the thread is avoided.
- FIG. 1 is a flow diagram of a dynamic hooking process in accordance with one embodiment of the present invention.
- one embodiment of the present invention adds an operation to function hooking through prologue overwrites whereby other threads in the process are checked to ensure they are not affected. A copy of the prologue that is being hooked is saved. If other threads in the process are being affected, the offset of the thread's instruction pointer into the prologue is calculated and the thread is redirected to the copy of the saved prologue, which then jumps back to the original function.
- a typical target function looks like the following: [Prologue] [Function body] [Epilogue]
- Hooking a function typically involves overwriting the usual prologue with a jump or call instruction to the hooking code.
- hooing a live process there will likely be several threads already running.
- the hooking process typically must suspend any and all threads of the target process.
- the hooking process further injects the code pages or hooking thread, save copies of the original prologues, overwrite the prologues of the functions to be hooked, and then resume execution of all threads.
- the thread context contains processor relevant information like state of the registers including the location where EIP points to.
- the EIP isn't within a region that was modified during hooking (e.g., check if the EIP lies within the prologue).
- FIG. 1 is a flow diagram of a dynamic hooking process 100 in accordance with one embodiment of the present invention.
- GET CONTEXT(S) OF SUSPENDED THREAD(S) OPERATION 106 the context of each suspended thread is obtained, e.g., using the Win32 API GetThreadContext.
- HOOK FUNCTION(S) OPERATION 107 the desired functions are hooked, for example, by overwriting the usual prologue with a jump or call instruction to the hooking code.
- the binary search tree is sorted based on the HookedPrologueStart field.
- GET EIP OF SUSPENDED THREAD OPERATION 112 the EIP for the suspended thread, sometimes called the “ThreadEIP”, is obtained, e.g., from the context of the suspended thread obtained in OPERATION 106 .
- ThreadEIP is less than PrologueStart or greater than or equal to PrologueEnd
- flow moves to RESUME THREAD OPERATION 116 and the thread is resumed.
- ThreadEIP is greater than or equal to PrologueStart and less than PrologueEnd
- flow moves to CHANGE CONTEXT OF THREAD OPERATION 118 .
- OPERATIONS 112 , 114 , 116 , and sometimes OPERATION 118 are performed on the thread selected in OPERATION 124 .
- OPERATIONS 120 , 124 , 112 , 114 , 116 , and sometimes 118 are performed until a determination is made that there are no additional suspended threads in ADDITIONAL SUSPENDED THREADS CHECK OPERATION 120 , and flow moves to and exits at EXIT OPERATION 122 .
- Operation 4 is calculating the offset of the thread's instruction pointer into the prologue and then redirecting it to the copy of the saved prologue, which then jumps back to the original function.
Abstract
A method of dynamically hooking runtime processes without interrupting the flow of execution includes: suspending a thread; hooking a function comprising modifying code of the function; and determining whether the thread was executing the modified code when the thread was suspended. If the thread was not executing the modified code, the thread is resumed. If the thread was executing the modified code, the context of the thread is changed to redirect the thread to a saved copy of the original prologue. In this manner, unpredictable behavior of the thread is avoided.
Description
1. Field of the Invention
The present invention relates to the protection of computer systems. More particularly, the present invention relates to hooking of runtime processes.
2. Description of the Related Art
The necessity of hooking runtime processes arises in various scenarios and situations like debugging, troubleshotting, profiling, extending functionality, etc. The challenge is to be able to successfully hook the function without interrupting the flow of execution.
When hooking a function via a prologue overwrite, the case that another thread was executing the prologue of the function that was hooked at the time it was hooked should be considered. With modern processors, the cache will become invalidated once the prologue is overwritten so that the CPU will execute the modified instructions. However, if it had executed only part of the prologue, this may create an invalid state that will crash the thread or the process.
A method of dynamically hooking runtime processes without interrupting the flow of execution includes: suspending a thread; hooking a function comprising modifying code of the function; and determining whether the thread was executing the modified code when the thread was suspended. If the thread was not executing the modified code, the thread is resumed. If the thread was executing the modified code, the context of the thread is changed to redirect the thread to a saved copy of the original prologue. In this manner, unpredictable behavior of the thread is avoided.
Embodiments in accordance with the present invention are best understood by reference to the following detailed description when read in conjunction with the accompanying drawings.
Common reference numerals are used throughout the drawings and detailed description to indicate like elements.
In the whole process of suspending the threads, altering the code structure and resuming the threads during hooking of function(s), there lies a possibility that the thread that was suspended was executing one of the functions that was hooked. If part of what the thread was executing was modified while it was suspended, the behavior of the thread after being resumed is unpredictable.
Because hooking functions should not disrupt the process, one embodiment of the present invention adds an operation to function hooking through prologue overwrites whereby other threads in the process are checked to ensure they are not affected. A copy of the prologue that is being hooked is saved. If other threads in the process are being affected, the offset of the thread's instruction pointer into the prologue is calculated and the thread is redirected to the copy of the saved prologue, which then jumps back to the original function.
More particularly, a typical target function (to be hooked) looks like the following: [Prologue] [Function body] [Epilogue]
Hooking a function typically involves overwriting the usual prologue with a jump or call instruction to the hooking code. When hooing a live process, there will likely be several threads already running.
The hooking process typically must suspend any and all threads of the target process. The hooking process further injects the code pages or hooking thread, save copies of the original prologues, overwrite the prologues of the functions to be hooked, and then resume execution of all threads.
In the whole process of suspending the threads, altering the code structure and resuming the threads there lies a possibility that the thread that was suspended was executing one of the functions that was hooked. If part of what the thread was executing was modified while it was suspended, the behavior of the thread after being resumed is unpredictable. Most modern processes will invalidate the cache and read in the modified instructions at the thread's instruction pointer, which may now be garbage.
Every thread has a context of execution at any point of time. Whenever the thread is suspended, the thread context needs to be examined. Win32 API GetThreadContext helps to get the context of the running thread.
The thread context contains processor relevant information like state of the registers including the location where EIP points to.
In accordance with one embodiment, it is verified that the EIP isn't within a region that was modified during hooking (e.g., check if the EIP lies within the prologue).
From an ENTER OPERATION 102, flow moves to a SUSPEND THREAD(S) OPERATION 104. In SUSPEND THREAD(S) OPERATION 104, any and all threads of the target process to be hooked are suspended.
From SUSPEND THREAD(S) OPERATION 104, flow moves to a GET CONTEXT(S) OF SUSPENDED THREAD(S) OPERATION 106. In GET CONTEXT(S) OF SUSPENDED THREAD(S) OPERATION 106, the context of each suspended thread is obtained, e.g., using the Win32 API GetThreadContext.
From GET CONTEXT(S) OF SUSPENDED THREAD(S) OPERATION 106, flow moves to a HOOK FUNCTION(S) OPERATION 207. In HOOK FUNCTION(S) OPERATION 107, the desired functions are hooked, for example, by overwriting the usual prologue with a jump or call instruction to the hooking code.
From HOOK FUNCTION(S) OPERATION 107, flow moves to an ARRANGE HOOKED FUNCTION(S) INTO A BINARY SEARCH TREE OPERATION 108. In ARRANGE HOOKED FUNCTION(S) INTO A BINARY SEARCH TREE OPERATION 108, each function that is hooked is arranged in a binary search tree with the following information:
HOOKED_FUNCTION
-
- DWORD HookedPrologueStart
- DWORD HookedPrologueEnd
- DWORD SavedPrologueStart
The binary search tree is sorted based on the HookedPrologueStart field.
From ARRANGE HOOKED FUNCTION(S) INTO A BINARY SEARCH TREE OPERATION 108, flow moves to a SELECT FIRST SUSPENDED THREAD OPERATION 110. In SELECT FIRST SUSPENDED THREAD OPERATION 110, the first suspended thread is selected.
From SELECT FIRST SUSPENDED THREAD OPERATION 110, flow moves to a GET EIP OF SUSPENDED THREAD OPERATION 112. In GET EIP OF SUSPENDED THREAD OPERATION 112, the EIP for the suspended thread, sometimes called the “ThreadEIP”, is obtained, e.g., from the context of the suspended thread obtained in OPERATION 106.
From GET EIP OF SUSPENDED THREAD OPERATION 112, flow moves to a PrologueStart<=ThreadEIP<PrologueEnd CHECK OPERATION 114. In PrologueStart<=ThreadEIP<PrologueEnd CHECK OPERATION 114, a determination is made as to whether PrologueStart<=ThreadEIP<PrologueEnd for any node in the binary search tree, i.e., whether the ThreadEIP is greater than or equal to PrologueStart and less the PrologueEnd. If the ThreadEIP is less than PrologueStart or greater than or equal to PrologueEnd, the suspended thread was not executing the hooked function. Conversely, if the ThreadEIP is greater than or equal to PrologueStart and less than PrologueEnd, the suspended thread was executing the hooked function.
Accordingly, if the ThreadEIP is less than PrologueStart or greater than or equal to PrologueEnd, flow moves to RESUME THREAD OPERATION 116 and the thread is resumed. Conversely, if the ThreadEIP is greater than or equal to PrologueStart and less than PrologueEnd, flow moves to CHANGE CONTEXT OF THREAD OPERATION 118.
In CHANGE CONTEXT OF THREAD OPERATION 118, the context structure of the thread is changed, e.g., using SetThreadContext, as follows:
-
- OffsetFromPrologueStart=ThreadContext->EIP−Node->HookedPrologueStart
- ThreadContext->EIP=Node->SavedPrologueStart+OffsetFromPrologueStart.
From CHANGE CONTEXT OF THREAD OPERATION 118, flow moves to RESUME THREAD OPERATION 116 and the thread is resumed.
From RESUME THREAD OPERATION 116, flow moves to an ADDITIONAL SUSPENDED THREADS CHECK OPERATION 120. In ADDITIONAL SUSPENDED THREADS CHECK OPERATION 120, a determination is made as to other there are any additional suspended threads.
If there are no additional suspended threads, flow moves to and exits at an EXIT OPERATION 122. Conversely, if there are additional suspended threads, flow moves to a SELECT NEXT SUSPENDED THREAD OPERATION 124.
In SELECT NEXT SUSPENDED THREAD OPERATION 124, the next suspended thread is selected for operation. OPERATIONS 112, 114, 116, and sometimes OPERATION 118, are performed on the thread selected in OPERATION 124. OPERATIONS 120, 124, 112, 114, 116, and sometimes 118, are performed until a determination is made that there are no additional suspended threads in ADDITIONAL SUSPENDED THREADS CHECK OPERATION 120, and flow moves to and exits at EXIT OPERATION 122.
In the above manner, the following operations to the end of the hooking prologue are added:
-
- 1. Enumerate through the list of threads in the process
- 2. Get the EIP field out of the thread's context (via GetThreadContext) and search through the binary search tree for a node that has a PrologueStart<=ThreadEIP>PrologueEnd.
- 3. If no matching nodes are found, resume the thread and repeat operation 1
- 4. If a matching node was found, it effectively means the code was pulled out from under the thread. We must now change the thread's context structure (e.g., SetThreadContext) as follows:
- OffsetFromPrologueStart=ThreadContext->EIP−Node->HookedPrologueStart
- ThreadContext->EIP=Node->SavedPrologueStart+OffsetFromPrologueStart
- 5. Resume the thread and repeat at operation 1
Operation 4 is calculating the offset of the thread's instruction pointer into the prologue and then redirecting it to the copy of the saved prologue, which then jumps back to the original function.
This disclosure provides exemplary embodiments of the present invention. The scope of the present invention is not limited by these exemplary embodiments. Numerous variations, whether explicitly provided for by the specification or implied by the specification or not, may be implemented by one of skill in the art in view of this disclosure.
Claims (18)
1. A method comprising:
suspending a thread;
hooking a function comprising modifying code of said function; and
determining whether said thread was executing said modified code when said thread was suspended.
2. The method of claim 1 further comprising getting a context of said thread.
3. The method of claim 2 wherein said context comprises a ThreadEIP of said thread.
4. The method of claim 3 wherein said determining comprises determining whethere said ThreadEIP is greater than or equal to a PrologueStart and less than a PrologueEnd.
5. The method of claim 4 further comprising resuming said thread if said ThreadEIP is less than said PrologueStart or greater than or equal to said PrologueEnd.
6. The method of clam 4 further comprising changing a context of said thread if said ThreadEIP is greater than or equal to said PrologueStart and less than said PrologueEnd.
7. The method of claim 6 wherein said changing a context of said thread comprises:
OffsetFromPrologueStart=ThreadContext->EIP−Node->HookedPrologueStart
ThreadContext->EIP=Node->SavedPrologueStart+OffsetFromPrologueStart.
8. The method of claim 1 wherein said hooking comprises overwriting a prologue with a jump or call instruction to a hooking code.
9. A method comprising:
suspending threads of a target process;
saving a copy of a prologue of said target process;
hooking said target process comprising overwriting said prologue; and
determining whether any of said threads was executing said prologue during said suspending.
10. The method of claim 9 wherein for any threads that were executing said prologue during said suspending, said method further comprising:
changing a context of said threads; and
resuming said threads.
11. The method of claim 10 wherein said changing a context of said threads comprising:
calculating an offset of the thread's instruction pointer into said prologue; and
redirecting the thread to said saved copy of said prologue.
12. The method of claim 9 wherein for any threads that were not executing said prologue during said suspending, said method further comprising resuming said threads.
13. The method of claim 9 wherein said prologue is overwritten with a jump or call instruction to hooking code during said hooking.
14. The method of claim 9 further comprising determining context of said threads using GetThreadContext.
15. The method of claim 9 wherein said determining whether any of said threads was executing said prologue during said suspending comprises determining whether EIP lies within the prologue.
16. The method of claim 9 wherein functions are hooked during said hooking, said method further comprising arranging said hooked functions into a binary search tree.
17. The method of claim 16 wherein each function that is hooked is arranged in said binary search tree with the following information:
HOOKED_FUNCTION
DWORD HookedPrologueStart
DWORD HookedPrologueEnd
DWORD SavedPrologueStart.
18. A method comprising:
(a) enumerating through a list of suspended threads in a process;
(b) getting an EIP field of the thread's context;
(c) search through a binary search tree for a node that has a PrologueStart<=ThreadEIP<PrologueEnd;
(d) if no matching nodes are found, resume the thread and repeat operation (a);
(e) if a matching node is found, change the thread's context structure as follows:
OffsetFromPrologueStart=ThreadContext->EIP−Node->HookedPrologueStart
ThreadContext->EIP=Node->SavedPrologueStart+OffsetFromPrologueStart; and
(f) Resume the thread and repeat at operation (a).
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US10/835,712 USH2202H1 (en) | 2004-04-28 | 2004-04-28 | Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US10/835,712 USH2202H1 (en) | 2004-04-28 | 2004-04-28 | Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution |
Publications (1)
Publication Number | Publication Date |
---|---|
USH2202H1 true USH2202H1 (en) | 2007-09-04 |
Family
ID=38457053
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
US10/835,712 Abandoned USH2202H1 (en) | 2004-04-28 | 2004-04-28 | Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution |
Country Status (1)
Country | Link |
---|---|
US (1) | USH2202H1 (en) |
Cited By (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7326576B2 (en) | 2003-04-09 | 2008-02-05 | Prescient Medical, Inc. | Raman spectroscopic monitoring of hemodialysis |
US7651851B2 (en) | 2005-01-27 | 2010-01-26 | Prescient Medical, Inc. | Handheld Raman body fluid analyzer |
US7688440B2 (en) | 2005-01-27 | 2010-03-30 | Prescient Medical, Inc. | Raman spectroscopic test strip systems |
US7716686B1 (en) * | 2006-02-14 | 2010-05-11 | Mcafee, Inc. | System, method and computer program product for interface hooking |
WO2013156655A1 (en) * | 2012-04-19 | 2013-10-24 | Universitat Politècnica De Catalunya | Method, system and an executable piece of code for controlling the use of hardware resources of a computer system |
WO2013156654A1 (en) * | 2012-04-19 | 2013-10-24 | Universitat Politècnica De Catalunya | Method, system and an executable piece of code for the virtualisation of a hardware resource associated with a computer system |
US11062028B2 (en) * | 2016-07-07 | 2021-07-13 | Deceptive Bytes Ltd. | Methods and systems for end-point malware prevention to refrain malware components from being executed |
Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20050166001A1 (en) * | 2004-01-22 | 2005-07-28 | Matthew Conover | Return-to-LIBC attack detection using branch trace records system and method |
-
2004
- 2004-04-28 US US10/835,712 patent/USH2202H1/en not_active Abandoned
Patent Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20050166001A1 (en) * | 2004-01-22 | 2005-07-28 | Matthew Conover | Return-to-LIBC attack detection using branch trace records system and method |
Cited By (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7326576B2 (en) | 2003-04-09 | 2008-02-05 | Prescient Medical, Inc. | Raman spectroscopic monitoring of hemodialysis |
US7651851B2 (en) | 2005-01-27 | 2010-01-26 | Prescient Medical, Inc. | Handheld Raman body fluid analyzer |
US7688440B2 (en) | 2005-01-27 | 2010-03-30 | Prescient Medical, Inc. | Raman spectroscopic test strip systems |
US7716686B1 (en) * | 2006-02-14 | 2010-05-11 | Mcafee, Inc. | System, method and computer program product for interface hooking |
WO2013156655A1 (en) * | 2012-04-19 | 2013-10-24 | Universitat Politècnica De Catalunya | Method, system and an executable piece of code for controlling the use of hardware resources of a computer system |
WO2013156654A1 (en) * | 2012-04-19 | 2013-10-24 | Universitat Politècnica De Catalunya | Method, system and an executable piece of code for the virtualisation of a hardware resource associated with a computer system |
US9176757B2 (en) | 2012-04-19 | 2015-11-03 | Universitat Politècnica De Catalunya | Method, system and an executable piece of code for the virtualization of a hardware resource associated with a computer system |
US9195505B2 (en) | 2012-04-19 | 2015-11-24 | Universitat Politécnica de Catalunya | Method, system and an executable piece of code for controlling the use of hardware resources of a computer system |
US11062028B2 (en) * | 2016-07-07 | 2021-07-13 | Deceptive Bytes Ltd. | Methods and systems for end-point malware prevention to refrain malware components from being executed |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US8266597B2 (en) | Dynamically patching computer code using breakpoints | |
Jula et al. | Deadlock Immunity: Enabling Systems to Defend Against Deadlocks. | |
JP6185487B2 (en) | Keeping secure data isolated from non-secure access when switching between domains | |
US9116717B2 (en) | Run-time interception of software methods | |
US7487502B2 (en) | Programmable event driven yield mechanism which may activate other threads | |
US7882321B2 (en) | Validity of address ranges used in semi-synchronous memory copy operations | |
US7734881B2 (en) | Adapting RCU for real-time operating system usage | |
US7849465B2 (en) | Programmable event driven yield mechanism which may activate service threads | |
US20110307858A1 (en) | Pre-compiling hosted managed code | |
US20060130061A1 (en) | Use of rollback RCU with read-side modifications to RCU-protected data structures | |
EP1600857A2 (en) | Thread rendezvous for read-only code in an object-oriented computing enviroment | |
US8056078B2 (en) | Cooperatively multitasking in an interrupt free computing environment | |
US20150286484A1 (en) | Processor subroutine cache | |
US10860716B2 (en) | Detecting malware concealed by delay loops of software programs | |
US9536084B1 (en) | Systems and methods for delivering event-filtered introspection notifications | |
USH2202H1 (en) | Method and apparatus to dynamically hook runtime processes without interrupting the flow of execution | |
US8108840B2 (en) | Method for enhancing debugger performance of hardware assisted breakpoints | |
EP1967950A2 (en) | Multiprocessor system for continuing program execution upon detection of abnormality | |
KR100498486B1 (en) | Computer system providing for recompiling a program and cxtracting threads dynamically by a thread binary compiler and Simultaneous Multithreading method thereof | |
KR20110057297A (en) | Dynamic analyzing system for malicious bot and methods therefore | |
US9531735B1 (en) | Systems and methods for delivering introspection notifications from a virtual machine | |
US10678595B2 (en) | Dynamic saving of registers in transactions | |
JP5577518B2 (en) | Memory management method, computer and memory management program | |
US20040103414A1 (en) | Method and apparatus for interprocess communications | |
JP5822848B2 (en) | Exception control method, system and program |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
AS | Assignment |
Owner name: SYMANTEC CORPORATION, CALIFORNIA Free format text: ASSIGNMENT OF ASSIGNORS INTEREST;ASSIGNORS:CONOVER, MATTHEW;SATISH, SOURABH;REEL/FRAME:015295/0133;SIGNING DATES FROM 20040407 TO 20040413 |
|
STCF | Information on status: patent grant |
Free format text: PATENTED CASE |