This is easy to find on the Internet.CodeI went there, and I was not bored with it. Unfortunately, when my laptop was decommissioned, I had to chew on the hard disk, and then I finally tried to write it for myself.
There are many ways to achieve this.
1. callwindowproc seems to be the name, and this Code is also available on the hard disk, but it is obviously slow.
The principle is that this API receives an address and runs without checking it. Therefore, we can build a series of ASM code in the memory.
When using this method, it should be noted that several parameters of the API function should be played, probably by pushing eax, then four POP ECx, then pop eax, and then our code.
2. threads and remote threads
This is the address that can be input when the thread starts, and then it runs, but it also involves some things. Don't talk about this.
3. Use Delegation
This is what we want to introduce, and there are many implementation methods. For example, some may declare an actual function, write ASM to it, and then call the corresponding delegate. Here we will introduce the getdelegateforfunctionpointer method and related steps:
1. preparations:
API statement and delegate statement:
Private Declare Function Virtualprotect Lib " Kernel32.dll " ( Byval Lpaddress As Intptr, Byval Dwsize As Integer , Byval Flnewprotect As Integer , Byref LpfloldprotectAs Integer ) As Integer Delegate Function Subarg (arg1 As Integer , Arg2 As Integer ) As Integer Dim Dlgt As Subarg
It doesn't need to be explained, that is, the API. subarg is the function form, and dlgt is the instantiated subarg. You only need to pay attention to the global issue of dlgt. Otherwise, GC may lose the commissioned tasks.
2. Preparations
O (distinct _ distinct) O ~
To facilitate the expression of the ASM code in string form (also using Byte arrays, but not very comfortable), write a function:
Private Function Str2bytes ( Str As String ) As Byte () Dim I As Integer Dim AssemblycodeAs String Assemblycode = Str . Replace ( Space ( 1 ), String . Empty) Dim Assemblyvalue ( Len (Assemblycode )\ 2 - 1 ) As Byte For I = 1 To Len (Assemblycode) Step 2 Assemblyvalue (I \ 2 ) = Val ( " & H " & Mid (Assemblycode, I, 2 )) Next Return Assemblyvalue End Function
There is nothing to say about this, that is, to use strings to represent them, and then use spaces to separate them to look clear.
3. Preparations
I am not afraid of eggs. After writing the function, I added a button.
Private Sub Button#click (sender As System. Object, E As System. eventargs) Handles Button1.click Dim BS () = Str2bytes (asmstr) Dim PTR As Intptr = Marshal. allochglobal (BS. length) Dim Lpfloldprotect As Integer Virtualprotect (PTR, 1 , & H40, lpfloldprotect) ' RW + E Marshal. Copy (BS, 0 , PTR, BS. Length) dlgt = Marshal. getdelegateforfunctionpointer (PTR,GetType (Subarg )) Msgbox ( " Currently, you can break a breakpoint on the displayed address to observe the function call status. " & HEX (PTR. toint32), msgboxstyle. okonly, " Function Assembly address " ) Dim T As Integer =My. Computer. Clock. tickcount Dim I, R As Integer , N As Integer = 10000000 For I = 0 To N- 1 R = Dlgt. Invoke ( 1 , 2 ) Next Debug. Print (R & " " & N \ (My. Computer. Clock. tickcount- T) Marshal. freehglobal (PTR) End sub
After a brief explanation, make sure to change the Memory attribute, which is generally read/write + run, and will not be restored anyway. The original memory page attribute will not be recorded, but it is best to reclaim the memory.
4. Preparation
--!!!
In fact, the above and the vast majority of Code are still the same, and then it is ASM. This is a big play. Generally, it is not easy to use the embedded ASM with no ASM accomplishments at all. In fact, I have no more points and I know no more than five commands. They are all currently used for queries. If you have a problem, you can use VC to write the function, and then use OD, IDA to see what the function is for reference. However, it is not acceptable to simply copy the function because there are some additional things in the function. The more "Orthodox" approach should be to use the ASM programming tool to write code and then compile the link. I usually use the Embedded Assembly of VC, because other tools are not used, I don't know where to open it --!
Here I wrote a simple function, that is, parameter 1 and parameter 2 are different:
Dim asmstr as string = "55 8bec "&_
"8b45 08 2b45 0C "&_
"5d C2 08 00"
Carefully analyze the origins of this function:
A. Create an mfc dll using VC. net, share the MFC, and the project name is subarg. (It doesn't matter. It's similar)
B. Write a function in subarg. cpp and return a-B directly. (Copy the comment above and make a slight change)
C. Change the configuration to release generation, and then OD or IDA. Analyze the code and eax returns the value. You can see some key code (IDA copies A and B are actually a representation of it, if it is od, we can see that mov sub writes 8, C respectively ):
A = dword ptr 8
B = DWORD PTR 0ch
Push EBP
MoV EBP, ESP
......
MoV eax, [EBP + A]
Sub eax, [EBP + B]
......
This is actually the case. There are some registers to be cleaned up and used to do some other things. In fact, we use an eax, so nothing else can be done. There may be something below, but the eax value is here. Of course, some items are cleared up when I return. But why isn't it in my code? In fact, I can use the ASM programming tool to write a sub-function and I will see it. This sub-function does not need to be restored. RET 8 means to discard 2 4 because there are 2 parameters. If one is RET 4, if three are ...... RET C
So our function is as follows:
Push EBP
MoV EBP, ESP
MoV eax, [EBP + 8]
Sub eax, [EBP + C]
Pop EBP
RET 8
Copy it directly from Dia. In fact, if you use OD, you just need to input the Assembly directly. CE and xuer can do anything.
The final result is:
DimAsmstrAs String="55 8bec"&_"8b45 08 2b45 0c"&_"5D C2 08 00"
A row corresponds to the preceding section. All the code is above, and the following is a complete copy:
View code
Imports System. runtime. interopservices Public Class Form1 Private Declare Function Virtualprotect Lib " Kernel32.dll " ( Byval Lpaddress As Intptr, Byval Dwsize As Integer ,Byval Flnewprotect As Integer , Byref Lpfloldprotect As Integer ) As Integer ' As the called function. Because there are two parameters, 8 digits are discarded. ' Push EBP 55 ' MoV EBP, esp 8B EC ' ============== Actual function ==================== ' MoV eax, [EBP + 8] 8b45 08 ' Sub eax, [EBP + C] 2b45 0c ' ====================================== ' Pop EBP 5D ' RET 8 C2 08 00 Dim Asmstr As String = " 55 8bec " & _ " 8b45 08 2b45 0c " & _ " 5D C2 08 00 " Delegate Function Subarg (arg1 As Integer , Arg2 As Integer ) As Integer Dim Dlgt As Subarg Private Sub Button#click (sender As System. Object, E As System. eventargs) Handles Button1.click Dim BS () = Str2bytes (asmstr) Dim PTR As Intptr = Marshal. allochglobal (BS. length) Dim Lpfloldprotect As Integer Virtualprotect (PTR, 1 , & H40, lpfloldprotect) ' RW + E Marshal. Copy (BS, 0 , PTR, BS. Length) dlgt = Marshal. getdelegateforfunctionpointer (PTR,GetType (Subarg )) Msgbox ( " Currently, you can break a breakpoint on the displayed address to observe the function call status. " & HEX (PTR. toint32), msgboxstyle. okonly, " Function Assembly address " ) Dim T As Integer =My. Computer. Clock. tickcount Dim I, R As Integer , N As Integer = 10000000 For I = 0 To N- 1 R = Dlgt. Invoke ( 1 , 2 ) Next Debug. Print (R & " " & N \ (My. Computer. Clock. tickcount- T) Marshal. freehglobal (PTR) End sub Private Function Str2bytes ( Str As String ) As Byte () Dim I As Integer Dim Assemblycode As String Assemblycode = Str . Replace ( Space ( 1 ), String . Empty) Dim Assemblyvalue (Len (Assemblycode )\ 2 - 1 ) As Byte For I = 1 To Len (Assemblycode) Step 2 Assemblyvalue (I \ 2 ) = Val ( " & H " & Mid (Assemblycode, I, 2 )) Next Return Assemblyvalue End Function End Class