Hope this helps with updates and for learning purpose
Main code :
on github:
Credits: spudgy
Main code :
C++:
RD64 DumpFnc(DWORD idx, bool bNotBones = false) {
DWORD DISP_VALUE = 0x19;
DWORD64 dwRet = 0;
CONTEXT c;
c = dbg.GetContext();
c.Rip = dbg.procBase + 0xEC49A4; //48 89 54 24 10 53 55 56 57 48 83 EC 38 80 BA 2C 0A 00 00 00 48 8B EA 65 4C 8B 04 25 58 00 00 00
c.Rcx = idx; //fnc index
dbg.SetContext(&c);
dbg.SingleStep();
c = dbg.GetContext();
c.Rip = dbg.procBase + 0xEC4A21;
if (bNotBones) { //not bones, scan for decrypt_key_for_entity
DISP_VALUE = 0x09;
c.Rax = idx;
c.Rip = dbg.procBase + 0xEDBB0B;
}
dbg.SetContext(&c);
dbg.SingleStep();
c = dbg.GetContext();
dbg.SingleStep();
c = dbg.GetContext();
dbg.SingleStep();
c = dbg.GetContext();
dwRet = c.Rax;
//loop till we find the end..
BYTE bEndSig[20] = { 0x4C ,0x8B ,0x7C ,0x24 ,0x20 ,0x4C ,0x8B ,0x74 ,0x24 ,0x28 ,0x4C ,0x8B ,0x6C ,0x24 ,0x30 ,0x4C ,0x8B ,0x64 ,0x24 ,0x60 };
BYTE bEndSig2[20] = { 0x44, 0x8B, 0x64, 0x24, 0x30, 0x44, 0x8B, 0x6C, 0x24, 0x34, 0x4C, 0x8B, 0x7C, 0x24, 0x40, 0x4C, 0x8B, 0x74, 0x24, 0x38 };
/*00007FF603397031 | 4C:8B7C24 20 | mov r15, qword ptr ss:[rsp + 0x20] |
00007FF603397036 | 4C:8B7424 28 | mov r14, qword ptr ss:[rsp + 0x28] |
00007FF60339703B | 4C:8B6C24 30 | mov r13, qword ptr ss:[rsp + 0x30] |
00007FF603397040 | 4C:8B6424 60 | mov r12, qword ptr ss:[rsp + 0x60] |*/
// Initialize decoder context.
ZydisDecoder decoder;
ZydisDecoderInit(
&decoder,
ZYDIS_MACHINE_MODE_LONG_64,
ZYDIS_ADDRESS_WIDTH_64);
// Initialize formatter. Only required when you actually plan to
// do instruction formatting ("disassembling"), like we do here.
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
// Loop over the instructions in our buffer.
// The IP is chosen arbitrary here in order to better visualize
// relative addressing.
uint64_t instructionPointer = 0x007FFFFFFF400000;
size_t offset = 0;
ZydisDecodedInstruction instruction;
DWORD64 oldRip = 0;
DWORD iImul = 0;
bool bLastKey = false;
DWORD64 dwKeys[4] = { 0,0,0,0 };
while(1) {
BYTE bRead[20];
dbg.ReadTo(c.Rip, bRead, 20);
//printf("F EIP: %p / %p / %p\n", c.Rip, c.Rdx, c.Rax);
if (!memcmp(bRead, bEndSig, 20) || !memcmp(bRead, bEndSig2, 20)) {
//printf("END SIG!\n");
break;
}
bool goodDec = ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(
&decoder, bRead, 20,
instructionPointer, &instruction));
//skip 00007FF603394F6D | 4C:8B41 0F | mov r8, qword ptr ds:[rcx + 0xF] |
if (goodDec && (instruction.mnemonic == ZYDIS_MNEMONIC_MOV || instruction.mnemonic == ZYDIS_MNEMONIC_IMUL) && instruction.operands[1].mem.disp.hasDisplacement && instruction.operands[1].mem.disp.value == DISP_VALUE) {
bLastKey = true;
//skip
c = dbg.GetContext();
c.Rip += 4; //fnc index
if (instruction.mnemonic == ZYDIS_MNEMONIC_IMUL) {
bLastKey = false;
iImul++;//skip lastKey
c.Rip++;
}
dbg.SetContext(&c);
continue;
}
oldRip = c.Rip;
dbg.SingleStep();
c = dbg.GetContext();
DWORD nInstructSize = c.Rip - oldRip;
{
if (goodDec && instruction.mnemonic == ZYDIS_MNEMONIC_IMUL) {
DWORD64 pReg = 0;
if (!bLastKey) {
if (goodDec) {
BYTE reg = instruction.operands[1].reg.value;
switch (reg) {
case ZYDIS_REGISTER_RAX:
pReg = c.Rax;
break;
case ZYDIS_REGISTER_RCX:
pReg = c.Rcx;
break;
case ZYDIS_REGISTER_RBP:
pReg = c.Rbp;
break;
case ZYDIS_REGISTER_RDI:
pReg = c.Rdi;
break;
case ZYDIS_REGISTER_R9:
pReg = c.R9;
break;
case ZYDIS_REGISTER_R10:
pReg = c.R10;
break;
case ZYDIS_REGISTER_R11:
pReg = c.R11;
break;
case ZYDIS_REGISTER_R12:
pReg = c.R12;
break;
case ZYDIS_REGISTER_R13:
pReg = c.R13;
break;
case ZYDIS_REGISTER_R14:
pReg = c.R14;
break;
case ZYDIS_REGISTER_R15:
pReg = c.R15;
break;
default:
printf("unk good zydis %i\n", reg);
break;
}
}
}
dwKeys[iImul++] = pReg;
bLastKey = false;
}
//check if imul
}
}
bool bGen = true;
if (bGen) {
if (dwKeys[0] == 0) printf("key[%i][0] = LastKey;\n",idx); else printf("key[%i][0] = 0x%p;\n", idx, dwKeys[0]);
if (dwKeys[1] == 0) printf("key[%i][1] = LastKey;\n",idx); else printf("key[%i][1] = 0x%p;\n", idx, dwKeys[1]);
if (dwKeys[2] == 0) printf("key[%i][2] = LastKey;\n", idx); else printf("key[%i][2] = 0x%p;\n", idx, dwKeys[2]);
if (dwKeys[3] == 0) printf("key[%i][3] = LastKey;\n\n", idx); else printf("key[%i][3] = 0x%p;\n\n", idx, dwKeys[3]);
}
else {
printf("%p - keys[%i] = { %p , %p , %p , %p }\n",dwRet, idx,dwKeys[0], dwKeys[1], dwKeys[2], dwKeys[3]);
//printf("key[%i] = { 0x%p , 0x%p , 0x%p , 0x%p }\n", idx, dwKeys[0], dwKeys[1], dwKeys[2], dwKeys[3]);
}
return dwRet;
}
on github:
Credits: spudgy