ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/Daodan/src/Daodan_Patch.c
(Generate patch)

Comparing Daodan/src/Daodan_Patch.c (file contents):
Revision 272 by rossy, Tue Mar 17 09:06:00 2009 UTC vs.
Revision 993 by alloc, Sun Apr 6 17:06:02 2014 UTC

# Line 1 | Line 1
1   #include "Daodan_Patch.h"
2 + #include "Daodan_Utility.h"
3 + #include <beaengine/BeaEngine.h>
4 +
5   #include <windows.h>
6 + #include <stdlib.h>
7 + #include <string.h>
8  
9   bool DDrPatch_MakeJump(void* from, void* to)
10   {
# Line 7 | Line 12 | bool DDrPatch_MakeJump(void* from, void*
12          
13          if (VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &oldp))
14          {
15 <                *(char*)from++ = 0xe9; // jmp rel32
15 >                *((unsigned char*)from) = 0xe9; // jmp rel32
16 >                from = (char*)from + 1;
17                  *(int*)from = (unsigned int)to - (unsigned int)from - 4;
18                  VirtualProtect(from, 5, oldp, &oldp);
19                  return true;
# Line 22 | Line 28 | bool DDrPatch_MakeCall(void* from, void*
28          
29          if (VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &oldp))
30          {
31 <                *(char*)from++ = 0xe8; // call rel32
31 >                *((unsigned char*)from) = 0xe8; // call rel32
32 >                from = (char*)from + 1;
33                  *(int*)from = (unsigned int)to - (unsigned int)from - 4;
34                  VirtualProtect(from, 5, oldp, &oldp);
35                  return true;
# Line 31 | Line 38 | bool DDrPatch_MakeCall(void* from, void*
38                  return false;
39   }
40  
41 < bool DDrPatch_String(char* dest, const char* string, int length)
41 > void* DDrPatch_MakeDetour(void* from, void* to)
42 > {
43 >        int len = 0;
44 > /*
45 >    DISASM MyDisasm;
46 >    int i = 0;
47 >    STARTUPMESSAGE("", 0);
48 >    STARTUPMESSAGE("", 0);
49 >
50 >    memset (&MyDisasm, 0, sizeof(DISASM));
51 >    MyDisasm.EIP = (UIntPtr) from;
52 >    i = 0;
53 >    STARTUPMESSAGE("Orig before @ 0x%06x", from);
54 >    while (i<10){
55 >        len = Disasm(&MyDisasm);
56 >        if (len != UNKNOWN_OPCODE) {
57 >                        STARTUPMESSAGE("%s, Opcode: 0x%x, len: %d, branch: %d, to: 0x%06x", MyDisasm.CompleteInstr, MyDisasm.Instruction.Opcode, len, MyDisasm.Instruction.BranchType, MyDisasm.Instruction.AddrValue);
58 >                        STARTUPMESSAGE("    Cat: 0x%04x, prefix count: %d", MyDisasm.Instruction.Category & 0xffff, MyDisasm.Prefix.Number );
59 >            MyDisasm.EIP += (UIntPtr)len;
60 >            i++;
61 >        }
62 >    };
63 >    STARTUPMESSAGE("", 0);
64 > */
65 >
66 >        DISASM disasm;
67 >        memset(&disasm, 0, sizeof(DISASM));
68 >        disasm.EIP = (UIntPtr) from;
69 >
70 >        char* trampoline = malloc(40);
71 >        DDrPatch_NOOP(trampoline, 40);
72 >        int pos = 0;
73 >        int branches = 0;
74 >
75 >        while (((void*)disasm.EIP - from) < 5) {
76 >                len = Disasm(&disasm);
77 >                if (len != UNKNOWN_OPCODE) {
78 >                        if ((disasm.Instruction.Category & 0xffff) == CONTROL_TRANSFER) {
79 >                                if (disasm.Prefix.Number > 0) {
80 >                                                STARTUPMESSAGE("Detour: Branch in trampoline area from address 0x%08x with prefixes", from);
81 >                                                return (void*)-1;
82 >                                }
83 >                                branches++;
84 >                                int target = disasm.Instruction.AddrValue;
85 >                                bool targetInTrampoline = ((void*)disasm.Instruction.AddrValue - from) < 5;
86 >                                switch (disasm.Instruction.BranchType) {
87 >                                        case JmpType:
88 >                                        case CallType:
89 >                                                if (targetInTrampoline) {
90 >                                                        int offset = disasm.Instruction.AddrValue - disasm.EIP;
91 >                                                        if (disasm.Instruction.BranchType == JmpType)
92 >                                                                DDrPatch_MakeJump(&trampoline[pos], &trampoline[pos]+offset);
93 >                                                        else
94 >                                                                DDrPatch_MakeCall(&trampoline[pos], &trampoline[pos]+offset);
95 >                                                } else {
96 >                                                        if (disasm.Instruction.BranchType == JmpType)
97 >                                                                DDrPatch_MakeJump(&trampoline[pos], (void*)target);
98 >                                                        else
99 >                                                                DDrPatch_MakeCall(&trampoline[pos], (void*)target);
100 >                                                }
101 >                                                pos += 5;
102 >                                                break;
103 >                                        case RetType:
104 >                                        case JECXZ:
105 >                                                memcpy(&trampoline[pos], (void*)disasm.EIP, len);
106 >                                                pos += len;
107 >                                                break;
108 >                                        // Opcode +1
109 >                                        case JO:
110 >                                        case JC:
111 >                                        case JE:
112 >                                        case JNA:
113 >                                        case JS:
114 >                                        case JP:
115 >                                        case JL:
116 >                                        case JNG:
117 >                                                if (targetInTrampoline) {
118 >                                                        memcpy(&trampoline[pos], (void*)disasm.EIP, len);
119 >                                                        pos += len;
120 >                                                } else {
121 >                                                        trampoline[pos++] = disasm.Instruction.Opcode + 1;
122 >                                                        trampoline[pos++] = 5;
123 >                                                        DDrPatch_MakeJump(&trampoline[pos], (void*)target);
124 >                                                        pos += 5;
125 >                                                }
126 >                                                break;
127 >                                        // Opcode -1
128 >                                        case JNO:
129 >                                        case JNC:
130 >                                        case JNE:
131 >                                        case JA:
132 >                                        case JNS:
133 >                                        case JNP:
134 >                                        case JNL:
135 >                                        case JG:
136 >                                                if (targetInTrampoline) {
137 >                                                        memcpy(&trampoline[pos], (void*)disasm.EIP, len);
138 >                                                        pos += len;
139 >                                                } else {
140 >                                                        trampoline[pos++] = disasm.Instruction.Opcode - 1;
141 >                                                        trampoline[pos++] = 5;
142 >                                                        DDrPatch_MakeJump(&trampoline[pos], (void*)target);
143 >                                                        pos += 5;
144 >                                                }
145 >                                                break;
146 >                                        default:
147 >                                                STARTUPMESSAGE("Detour: Unknown branch in trampoline area from address 0x%08x", from);
148 >                                                return (void*)-1;
149 >                                }
150 >                        } else {
151 >                                memcpy(&trampoline[pos], (void*)disasm.EIP, len);
152 >                                pos += len;
153 >                        }
154 >                        disasm.EIP += (UIntPtr)len;
155 >                }
156 >                else {
157 >                        STARTUPMESSAGE("Detour: Unknown opcode in trampoline area from address 0x%08x", from);
158 >                        return (void*)-1;
159 >                }
160 >        }
161 >
162 >        if (branches > 1) {
163 >                STARTUPMESSAGE("Detour: Too many branches in trampoline'd code from address 0x%08x: %d", from, branches);
164 >                return (void*)-1;
165 >        }
166 >
167 >
168 >        DDrPatch_MakeJump(&trampoline[pos], (void*)disasm.EIP);
169 >        DDrPatch_NOOP(from, (void*)disasm.EIP - from);
170 >
171 >        DWORD oldp;
172 >        if (!VirtualProtect(trampoline, 40, PAGE_EXECUTE_READWRITE, &oldp)) {
173 >                STARTUPMESSAGE("Detour: Could not mark page for trampoline as executable: from address 0x%08x", from);
174 >                return (void*)-1;
175 >        }
176 >        DDrPatch_MakeJump(from, to);
177 > /*
178 >    memset (&MyDisasm, 0, sizeof(DISASM));
179 >    MyDisasm.EIP = (UIntPtr) trampoline;
180 >    i = 0;
181 >    STARTUPMESSAGE("Trampoline @ 0x%06x", trampoline);
182 >    while (i<10){
183 >        len = Disasm(&MyDisasm);
184 >        if (len != UNKNOWN_OPCODE) {
185 >            STARTUPMESSAGE("%s", MyDisasm.CompleteInstr);
186 >            MyDisasm.EIP += (UIntPtr)len;
187 >            i++;
188 >        }
189 >    };
190 >    STARTUPMESSAGE("", 0);
191 >    
192 >    memset (&MyDisasm, 0, sizeof(DISASM));
193 >    MyDisasm.EIP = disasm.EIP;
194 >    i = 0;
195 >    STARTUPMESSAGE("Orig after @ 0x%06x", disasm.EIP);
196 >    while (i<7){
197 >        len = Disasm(&MyDisasm);
198 >        if (len != UNKNOWN_OPCODE) {
199 >            STARTUPMESSAGE("%s", MyDisasm.CompleteInstr);
200 >            MyDisasm.EIP += (UIntPtr)len;
201 >            i++;
202 >        }
203 >    };
204 >    STARTUPMESSAGE("", 0);
205 >
206 >    memset (&MyDisasm, 0, sizeof(DISASM));
207 >    MyDisasm.EIP = (UIntPtr) from;
208 >    i = 0;
209 >    STARTUPMESSAGE("Orig start after @ 0x%06x", from);
210 >    while (i<3){
211 >        len = Disasm(&MyDisasm);
212 >        if (len != UNKNOWN_OPCODE) {
213 >            STARTUPMESSAGE("%s", MyDisasm.CompleteInstr);
214 >            MyDisasm.EIP += (UIntPtr)len;
215 >            i++;
216 >        }
217 >    };
218 >    STARTUPMESSAGE("", 0);
219 >    STARTUPMESSAGE("", 0);
220 >    STARTUPMESSAGE("", 0);
221 > */
222 >
223 >        return trampoline;
224 > }
225 >
226 > bool DDrPatch_String(char* dest, const unsigned char* string, int length)
227   {
228          DWORD oldp;
229          
# Line 45 | Line 237 | bool DDrPatch_String(char* dest, const c
237                  return false;
238   }
239  
240 < bool DDrPatch_Byte(char* dest, char value)
240 > bool DDrPatch_Byte(char* dest, unsigned char value)
241   {
242          DWORD oldp;
243          
# Line 59 | Line 251 | bool DDrPatch_Byte(char* dest, char valu
251                  return false;
252   }
253  
254 < bool DDrPatch_Int32(int* dest, int value)
254 > bool DDrPatch_Int32(int* dest, unsigned int value)
255   {
256          DWORD oldp;
257          
# Line 73 | Line 265 | bool DDrPatch_Int32(int* dest, int value
265                  return false;
266   }
267  
268 < bool DDrPatch_Int16(short* dest, short value)
268 > bool DDrPatch_Int16(short* dest, unsigned short value)
269   {
270          DWORD oldp;
271          
# Line 84 | Line 276 | bool DDrPatch_Int16(short* dest, short v
276                  return true;
277          }
278          else
279 +                return false;
280 + }
281 +
282 + bool DDrPatch__strdup(int* dest, const char* value)
283 + {
284 +        DWORD oldp;
285 +        
286 +        if (VirtualProtect(dest, 4, PAGE_EXECUTE_READWRITE, &oldp))
287 +        {
288 +                *dest = (int)_strdup(value);
289 +                VirtualProtect(dest, 4, oldp, &oldp);
290 +                return true;
291 +        }
292 +        else
293 +                return false;
294 + }
295 +
296 + bool DDrPatch_NOOP(char* dest, unsigned int length)
297 + {
298 +        DWORD oldp;
299 +        
300 +        if (VirtualProtect(dest, length, PAGE_EXECUTE_READWRITE, &oldp))
301 +        {
302 +                memset(dest, 0x90, length);
303 +                VirtualProtect(dest, length, oldp, &oldp);
304 +                return true;
305 +        }
306 +        else
307                  return false;
308   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)