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 689 by alloc, Mon Mar 4 15:52:19 2013 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>
# Line 35 | Line 38 | bool DDrPatch_MakeCall(void* from, void*
38                  return false;
39   }
40  
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;

Diff Legend

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