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 983 by alloc, Sun Mar 16 20:06:52 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 +    DDrStartupMessage("");
48 +    DDrStartupMessage("");
49 +
50 +    memset (&MyDisasm, 0, sizeof(DISASM));
51 +    MyDisasm.EIP = (UIntPtr) from;
52 +    i = 0;
53 +    DDrStartupMessage("Orig before @ 0x%06x", from);
54 +    while (i<10){
55 +        len = Disasm(&MyDisasm);
56 +        if (len != UNKNOWN_OPCODE) {
57 +                        DDrStartupMessage("%s, Opcode: 0x%x, len: %d, branch: %d, to: 0x%06x", MyDisasm.CompleteInstr, MyDisasm.Instruction.Opcode, len, MyDisasm.Instruction.BranchType, MyDisasm.Instruction.AddrValue);
58 +                        DDrStartupMessage("    Cat: 0x%04x, prefix count: %d", MyDisasm.Instruction.Category & 0xffff, MyDisasm.Prefix.Number );
59 +            MyDisasm.EIP += (UIntPtr)len;
60 +            i++;
61 +        }
62 +    };
63 +    DDrStartupMessage("");
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 +                                                DDrStartupMessage("Daodan: 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 +                                                DDrStartupMessage("Daodan: 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 +                        DDrStartupMessage("Daodan: Detour: Unknown opcode in trampoline area from address 0x%08x", from);
158 +                        return (void*)-1;
159 +                }
160 +        }
161 +
162 +        if (branches > 1) {
163 +                DDrStartupMessage("Daodan: 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 +        DDrPatch_MakeJump(from, to);
171 + /*
172 +    memset (&MyDisasm, 0, sizeof(DISASM));
173 +    MyDisasm.EIP = (UIntPtr) trampoline;
174 +    i = 0;
175 +    DDrStartupMessage("Trampoline @ 0x%06x", trampoline);
176 +    while (i<10){
177 +        len = Disasm(&MyDisasm);
178 +        if (len != UNKNOWN_OPCODE) {
179 +            DDrStartupMessage(MyDisasm.CompleteInstr);
180 +            MyDisasm.EIP += (UIntPtr)len;
181 +            i++;
182 +        }
183 +    };
184 +    DDrStartupMessage("");
185 +    
186 +    memset (&MyDisasm, 0, sizeof(DISASM));
187 +    MyDisasm.EIP = disasm.EIP;
188 +    i = 0;
189 +    DDrStartupMessage("Orig after @ 0x%06x", disasm.EIP);
190 +    while (i<7){
191 +        len = Disasm(&MyDisasm);
192 +        if (len != UNKNOWN_OPCODE) {
193 +            DDrStartupMessage(MyDisasm.CompleteInstr);
194 +            MyDisasm.EIP += (UIntPtr)len;
195 +            i++;
196 +        }
197 +    };
198 +    DDrStartupMessage("");
199 +
200 +    memset (&MyDisasm, 0, sizeof(DISASM));
201 +    MyDisasm.EIP = (UIntPtr) from;
202 +    i = 0;
203 +    DDrStartupMessage("Orig start after @ 0x%06x", from);
204 +    while (i<3){
205 +        len = Disasm(&MyDisasm);
206 +        if (len != UNKNOWN_OPCODE) {
207 +            DDrStartupMessage(MyDisasm.CompleteInstr);
208 +            MyDisasm.EIP += (UIntPtr)len;
209 +            i++;
210 +        }
211 +    };
212 +    DDrStartupMessage("");
213 +    DDrStartupMessage("");
214 +    DDrStartupMessage("");
215 +     */
216 +        return trampoline;
217 + }
218 +
219   bool DDrPatch_String(char* dest, const unsigned char* string, int length)
220   {
221          DWORD oldp;

Diff Legend

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