2023年12月18日发(作者:)
cmp eax, 1; // cmp eax, 1 je _move_1; // je _move_1 cmpsw; // cmps word ptr [rsi], word ptr [rdi] jnz _ret_false; // jnz _ret_false cmp eax, 2; // cmp eax, 2 je _move_0; // je _move_0 _move_1: cmpsb; // cmps byte ptr [rsi], byte ptr [rdi] jnz _ret_false; // jnz _ret_false _move_0:
mov IsOk, 1; // mov byte ptr [result], 1 _ret_false:
pop esi; // pop rsi pop edi; // pop rdi X64_End(); }#endif return IsOk;}DWORD64 GetFunctionAddressFromExportTable64(WCHAR* ModuleName,char* FunctionName){ DWORD* AddressOfFunctions = 0; WORD* AddressOfNameOrdinals = 0; DWORD* AddressOfNames = 0; DWORD64 ModuleBase = GetModuleHandle64(ModuleName); if (0 == ModuleBase) return 0; __try { IMAGE_DOS_HEADER ImageDosHeader; GetMemoy64(&ImageDosHeader, ModuleBase, sizeof(IMAGE_DOS_HEADER)); IMAGE_NT_HEADERS64 ImageNtHeaders; GetMemoy64(&ImageNtHeaders, ModuleBase + ImageDosHeader.e_lfanew, sizeof(IMAGE_NT_HEADERS64)); IMAGE_DATA_DIRECTORY& ImageDataDirectory = rectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; if (0 == lAddress) return 0; IMAGE_EXPORT_DIRECTORY ImageExportDirectory; GetMemoy64(&ImageExportDirectory, ModuleBase + lAddress, sizeof(IMAGE_EXPORT_DIRECTORY)); AddressOfFunctions = (DWORD*)malloc(sizeof(DWORD)*OfFunctions); if (NULL == AddressOfFunctions) { return 0; } //得到函数地址数组 GetMemoy64(AddressOfFunctions, ModuleBase + sOfFunctions,
sizeof(DWORD)*OfFunctions); AddressOfNameOrdinals = (WORD*)malloc(sizeof(WORD)*OfFunctions); if (NULL == AddressOfNameOrdinals) { return 0; } //得到索引数组 GetMemoy64(AddressOfNameOrdinals, ModuleBase + sOfNameOrdinals,
sizeof(WORD)*OfFunctions); AddressOfNames = (DWORD*)malloc(sizeof(DWORD)*OfNames);
AddressOfNames = (DWORD*)malloc(sizeof(DWORD)*OfNames); if (nullptr == AddressOfNames) { return 0; } //根据函数名得到函数索引 GetMemoy64(AddressOfNames, ModuleBase + sOfNames,
sizeof(DWORD)*OfNames); for (DWORD i = 0; i < OfFunctions; i++) { if (!CompareMemory64(FunctionName, ModuleBase + AddressOfNames[i], strlen(FunctionName) + 1)) continue; else //根据索引得到函数相对地址 基地址+相对地址=函数绝对地址 return ModuleBase + AddressOfFunctions[AddressOfNameOrdinals[i]]; } } __finally { if (AddressOfFunctions != NULL) { free(AddressOfFunctions); AddressOfFunctions = NULL; } if (AddressOfNameOrdinals != NULL) { free(AddressOfNameOrdinals); AddressOfNameOrdinals = NULL; } if (AddressOfNames != NULL) { free(AddressOfNames); AddressOfNames = NULL; } } return 0;}DWORD64 GetProcAddress64(DWORD64 ModuleBase, char* FunctionName){ //GetProcAddress() //得到函数地址 if (0 == __LdrGetProcedureAddress) { __LdrGetProcedureAddress = GetFunctionAddressFromExportTable64(L"", "LdrGetProcedureAddress"); // //v1 = 0x00007ffd30193560 if (0 == __LdrGetProcedureAddress) return 0; } _UNICODE_STRING_T
//64 rcx rdx r8 r9 [][][][][][]
//64 rcx rdx r8 r9 [][][][][][] //四寄存器赋值 va_list v1; va_start(v1, ParameterCount); Register64 _rcx = { (ParameterCount > 0) ? ParameterCount--, va_arg(v1, DWORD64) : 0 }; Register64 _rdx = { (ParameterCount > 0) ? ParameterCount--, va_arg(v1, DWORD64) : 0 }; Register64 _r8 = { (ParameterCount > 0) ? ParameterCount--, va_arg(v1, DWORD64) : 0 }; Register64 _r9 = { (ParameterCount > 0) ? ParameterCount--, va_arg(v1, DWORD64) : 0 }; Register64 _rax = { 0 }; //剩余参数 Register64 restArgs = { (DWORD64)&va_arg(v1, DWORD64) }; // conversion to QWORD for easier use in inline assembly#ifdef _M_IX86 Register64 _argC = { (DWORD64)ParameterCount }; //剩余参数数量 DWORD back_esp = 0; WORD back_fs = 0;
__asm { // reset FS segment, to properly handle RFG //重置fs段寄存器 mov back_fs, fs mov eax, 0x2B mov fs, ax // keep original esp in back_esp variable // 保存esp mov back_esp, esp
// align esp to 0x10, without aligned stack some syscalls may return errors ! // (actually, for syscalls it is sufficient to align to 8, but SSE opcodes
// requires 0x10 alignment), it will be further adjusted according to the // number of arguments above 4 //esp地址对齐 and esp, 0xFFFFFFF0 //准备ok 开始切换 X64_Start(); // below code is compiled as x86 inline asm, but it is executed as x64 code // that's why it need sometimes REX_W() macro, right column contains detailed // transcription how it will be interpreted by CPU // fill first four arguments //压四个寄存器 REX_W mov ecx, _[0];// mov rcx, qword ptr [_rcx] REX_W mov edx, _[0];// mov rdx, qword ptr [_rdx] push _64;// push qword ptr [_r8] X64_Pop(_R8); ;// pop r8 push _64;// push qword ptr [_r9] X64_Pop(_R9); ;// pop r9 //剩余寄存器数量 REX_W mov eax, _[0];// mov rax, qword ptr [_argC]
// final stack adjustment, according to the
// number of arguments above 4 //剩余参数压栈 push test al, 1; // test al, 1 jnz no_adjust; // jnz _no_adjust sub esp, 8; // sub rsp, 8 no_adjust: push edi; // push rdi REX_W mov edi, [0]; // mov rdi, qword ptr [restArgs] // put rest of arguments on the stack
REX_W test eax, eax;// test rax, rax jz _ls_e; // je _ls_e
jz _ls_e; // je _ls_e REX_W lea edi, dword ptr[edi + 8 * eax - 8];// lea rdi, [rdi + rax*8 - 8] _ls: REX_W test eax, eax; // test rax, rax jz _ls_e; // je _ls_e push dword ptr[edi]; // push qword ptr [rdi] REX_W sub edi, 8; // sub rdi, 8 REX_W sub eax, 1; // sub rax, 1 jmp _ls; // jmp _ls _ls_e:
// create stack space for spilling registers
REX_W sub esp, 0x20; // sub rsp, 20h call FunctionAddresss; // call qword ptr [func] // cleanup stack
REX_W mov ecx, _[0]; // mov rcx, qword ptr [_argC] REX_W lea esp, dword ptr[esp + 8 * ecx + 0x20]; // lea rsp, [rsp + rcx*8 + 20h]
pop edi; // pop rdi
// set return value
REX_W mov _[0], eax;// mov qword ptr [_rax], rax X64_End(); mov ax, ds mov ss, ax mov esp, back_esp // restore FS segment mov ax, back_fs mov fs, ax }#endif // _M_IX86 return _64;}


发布评论