static void cbOpenMutexA() { char mutex_name[20]=""; long mutex_addr=0; long esp_addr=0; unsigned int return_addr=0; DeleteAPIBreakPoint((char*)"kernel32.dll", (char*)"OpenMutexA", UE_APISTART); esp_addr=(long)GetContextData(UE_ESP); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)esp_addr, &return_addr, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)(esp_addr+12), &mutex_addr, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)mutex_addr, &mutex_name, 20, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } CreateMutexA(0, FALSE, mutex_name); if(GetLastError()==ERROR_SUCCESS) SetAPIBreakPoint((char*)"kernel32.dll", (char*)"VirtualProtect", UE_BREAKPOINT, UE_APISTART, (void*)cbVirtualProtect); else { char log_message[256]=""; sprintf(log_message, "[Fail] Failed to create mutex %s", mutex_name); VF_FatalError(log_message, g_ErrorMessageCallback); } }
static void cbDw() { unsigned int eip=GetContextData(UE_EIP); DeleteBPX(eip); BYTE* eip_data=(BYTE*)malloc2(0x1000); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (void*)eip, eip_data, 0x1000, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } unsigned int and20=VF_FindAnd20Pattern(eip_data, 0x1000); unsigned int minusreg=0; if(!and20) { and20=VF_FindShrPattern(eip_data, 0x1000); if(!and20) { VF_FatalError("Could not find 'and [reg],20", g_ErrorMessageCallback); return; } minusreg=8; } unsigned int andreg=eip_data[and20+1]&0x0F; andreg-=minusreg; g_extra_options_reg=0xFFFFFFFF; switch(andreg) { case 0: g_extra_options_reg=UE_EAX; break; case 1: g_extra_options_reg=UE_ECX; break; case 2: g_extra_options_reg=UE_EDX; break; case 3: g_extra_options_reg=UE_EBX; break; case 5: g_extra_options_reg=UE_EBP; break; case 6: g_extra_options_reg=UE_ESI; break; case 7: g_extra_options_reg=UE_EDI; break; } if(g_extra_options_reg==0xFFFFFFFF) VF_FatalError("Could not determine the register (extradw)", g_ErrorMessageCallback); free2(eip_data); SetBPX(and20+eip, UE_BREAKPOINT, (void*)cbDwordRetrieve); }
/********************************************************************** * Functions *********************************************************************/ static void cbGetVersion() { DeleteBPX(GetContextData(UE_EIP)); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (void*)g_version_decrypt_buffer, g_szVersion, 10, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } StopDebug(); }
static void cbOnDecryptVersion() { DeleteBPX(GetContextData(UE_EIP)); unsigned int esp=GetContextData(UE_ESP); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (void*)(esp+4), &g_version_decrypt_buffer, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } SetBPX((g_version_decrypt_call+5), UE_BREAKPOINT, (void*)cbGetVersion); }
static void cbDecryptCall() { DeleteBPX(GetContextData(UE_EIP)); unsigned int esp=GetContextData(UE_ESP); unsigned int retn=0; if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (void*)esp, &retn, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } SetBPX(retn, UE_BREAKPOINT, (void*)cbReturnDecryptCall); }
static void cbVirtualProtect() { DeleteAPIBreakPoint((char*)"kernel32.dll", (char*)"VirtualProtect", UE_APISTART); MEMORY_BASIC_INFORMATION mbi= {0}; unsigned int sec_addr=0; unsigned int sec_size=0; unsigned int esp_addr=0; BYTE* sec_data=0; esp_addr=(long)GetContextData(UE_ESP); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)((esp_addr)+4), &sec_addr, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } sec_addr-=0x1000; VirtualQueryEx(g_fdProcessInfo->hProcess, (void*)sec_addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); sec_size=mbi.RegionSize; sec_data=(BYTE*)malloc2(sec_size); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)sec_addr, sec_data, sec_size, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } unsigned int usbdevice=VF_FindUsbPattern(sec_data, sec_size); if(usbdevice) { usbdevice+=sec_addr; unsigned int usb_push=VF_FindPushAddr(sec_data, sec_size, usbdevice); if(!usb_push) VF_FatalError("Could not find reference to 'USB Device'", g_ErrorMessageCallback); unsigned int invalidkey=0; for(int i=usb_push; i>0; i--) { if(sec_data[i]==0x68 and (sec_data[i+5]>>4)==0x0B and sec_data[i+10]==0xE8) //if(sec_data[i]==0x6A and(sec_data[i+1]>>4)==0x00 and sec_data[i+2]==0x6A and(sec_data[i+3]>>4)==0x00 and sec_data[i+4]==0x68) { invalidkey=i; break; } } if(!invalidkey) VF_FatalError("Could not find InvalidKey pushes", g_ErrorMessageCallback); unsigned int extradw_call=0; unsigned int dw_extracall=0; DISASM MyDisasm; memset(&MyDisasm, 0, sizeof(DISASM)); MyDisasm.EIP=(UIntPtr)sec_data+invalidkey; int len=0; int call_count=0; for(;;) { len=Disasm(&MyDisasm); if(len!=UNKNOWN_OPCODE) { if(!strncasecmp(MyDisasm.Instruction.Mnemonic, "call", 4)) call_count++; if(call_count==2) break; MyDisasm.EIP=MyDisasm.EIP+(UIntPtr)len; if(MyDisasm.EIP>=(unsigned int)sec_data+invalidkey+0x1000) //Safe number (make bigger when needed) break; } else break; } extradw_call=MyDisasm.EIP-((unsigned int)sec_data); memcpy(&dw_extracall, sec_data+extradw_call+1, 4); unsigned int extradw_call_dest=(extradw_call+sec_addr)+dw_extracall+5; SetBPX(extradw_call_dest, UE_BREAKPOINT, (void*)cbDw); } else {
static void cbVirtualProtect() { MEMORY_BASIC_INFORMATION mbi= {0}; unsigned int sec_addr=0; unsigned int sec_size=0; unsigned int esp_addr=0; BYTE* sec_data=0; esp_addr=(long)GetContextData(UE_ESP); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)((esp_addr)+4), &sec_addr, 4, 0)) { VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } sec_addr-=0x1000; VirtualQueryEx(g_fdProcessInfo->hProcess, (void*)sec_addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); sec_size=mbi.RegionSize; sec_data=(BYTE*)malloc2(sec_size); if(!ReadProcessMemory(g_fdProcessInfo->hProcess, (const void*)sec_addr, sec_data, sec_size, 0)) { free2(sec_data); VF_FatalError(rpmerror(), g_ErrorMessageCallback); return; } if(*(unsigned short*)sec_data != 0x5A4D) //not a PE file { free2(sec_data); return; } DeleteAPIBreakPoint((char*)"kernel32.dll", (char*)"VirtualProtect", UE_APISTART); unsigned int armversion_addr=VF_FindarmVersion(sec_data, sec_size); if(!armversion_addr) { free2(sec_data); VF_FatalError("Could not find '<armVersion'", g_ErrorMessageCallback); return; } armversion_addr+=sec_addr; unsigned int push_addr=VF_FindPushAddr(sec_data, sec_size, armversion_addr); if(!push_addr) { free2(sec_data); VF_FatalError("Could not find reference to '<armVersion'", g_ErrorMessageCallback); return; } int call_decrypt=push_addr; while(sec_data[call_decrypt]!=0xE8) //TODO: fix this!! call_decrypt--; unsigned int call_dw=0; memcpy(&call_dw, (sec_data+call_decrypt+1), 4); unsigned int call_dest=(call_decrypt+sec_addr)+call_dw+5; unsigned int push100=0; for(int i=call_decrypt; i>0; i--) { if(sec_data[i]==0x68 and sec_data[i+1]==0x00 and sec_data[i+2]==0x01 and sec_data[i+3]==0x00 and sec_data[i+4]==0x00) { push100=i; break; } } if(!push100) { VF_FatalError("Could not find 'push 100'", g_ErrorMessageCallback); return; } //push_addr+=sec_addr; //TODO: remove this call_decrypt+=sec_addr; push100+=sec_addr; g_version_decrypt_call=call_decrypt; g_version_decrypt_call_dest=call_dest; g_version_decrypt_neweip=push100; SetBPX(g_version_decrypt_call_dest, UE_BREAKPOINT, (void*)cbDecryptCall); free2(sec_data); }