| 182 | } |
| 183 | |
| 184 | PUCHAR DetourSkipJmp(PUCHAR pCode, PVOID* ppGlobals) { |
| 185 | if (pCode == nullptr) { |
| 186 | return nullptr; |
| 187 | } |
| 188 | if (ppGlobals != nullptr) { |
| 189 | *ppGlobals = nullptr; |
| 190 | } |
| 191 | |
| 192 | // First, skip over the import vector if there is one |
| 193 | if (pCode[0] == 0xff && pCode[1] == 0x25) { // jmp [+imm32] |
| 194 | // Looks like an import alias jump, then get the code it points to. |
| 195 | PUCHAR pTarget = *(UNALIGNED PUCHAR*) & pCode[2]; |
| 196 | if (DetourIsImported(pCode, pTarget)) { |
| 197 | PUCHAR pNew = *(UNALIGNED PUCHAR*)pTarget; |
| 198 | LogDebug("%p->%p: skipped over import table.", pCode, pNew); |
| 199 | pCode = pNew; |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // Then, skip over a patch jump |
| 204 | if (pCode[0] == 0xeb) { // jmp +imm8 |
| 205 | PUCHAR pNew = pCode + 2 + *(CHAR*)&pCode[1]; |
| 206 | LogDebug("%p->%p: skipped over short jump.\n", pCode, pNew); |
| 207 | pCode = pNew; |
| 208 | |
| 209 | // First, skip over the import vector if there is one. |
| 210 | if (pCode[0] == 0xff && pCode[1] == 0x25) { // jmp [+imm32] |
| 211 | // Looks like an import alias jump, then get the code it points to. |
| 212 | PUCHAR pTarget = *(UNALIGNED PUCHAR*) & pCode[2]; |
| 213 | if (DetourIsImported(pCode, pTarget)) { |
| 214 | pNew = *(UNALIGNED PUCHAR*)pTarget; |
| 215 | LogDebug("%p->%p: skipped over import table.\n", pCode, pNew); |
| 216 | pCode = pNew; |
| 217 | } |
| 218 | } |
| 219 | // Finally, skip over a long jump if it is the target of the patch jump. |
| 220 | else if (pCode[0] == 0xe9) { |
| 221 | pNew = pCode + 5 + *(UNALIGNED INT32*) & pCode[1]; |
| 222 | LogDebug("%p->%p: skipped over long jump.\n", pCode, pNew); |
| 223 | pCode = pNew; |
| 224 | } |
| 225 | } |
| 226 | return pCode; |
| 227 | } |
| 228 | |
| 229 | void DetourFindJmpBounds(PUCHAR pCode, PDETOUR_TRAMPOLINE* ppLower, |
| 230 | PDETOUR_TRAMPOLINE* ppUpper) { |
no test coverage detected