DWORD64 Wow64Local::GetModuleHandle64( wchar_t* lpModuleName, DWORD* pSize /*= nullptr*/ ) { DWORD64 module = 0; TEB64 teb64 = {0}; PEB64 peb64 = {0}; PEB_LDR_DATA64 ldr = {0}; getTEB64(teb64); memcpy64((DWORD64)&peb64, teb64.ProcessEnvironmentBlock, sizeof(peb64)); memcpy64((DWORD64)&ldr, peb64.Ldr, sizeof(ldr)); // Traverse 64bit modules for(DWORD64 head = ldr.InLoadOrderModuleList.Flink; head != (peb64.Ldr + FIELD_OFFSET(PEB_LDR_DATA64, InLoadOrderModuleList)); memcpy64((DWORD64)&head, (DWORD64)head, sizeof(head))) { wchar_t localbuf[512] = {0}; LDR_DATA_TABLE_ENTRY64 localdata = {0}; memcpy64((DWORD64)&localdata, head, sizeof(localdata)); memcpy64((DWORD64)localbuf, localdata.BaseDllName.Buffer, localdata.BaseDllName.Length); if (_wcsicmp(localbuf, lpModuleName) == 0) { module = localdata.DllBase; if(pSize) *pSize = localdata.SizeOfImage; break; } } return module; }
inline void ssmp_recv_color_platf(ssmp_color_buf_t* cbuf, ssmp_msg_t* msg) { uint32_t num_ues = cbuf->num_ues; SSMP_FLAG_TYPE** cbuf_state = cbuf->buf_state; uint32_t start_recv_from; while(1) { for (start_recv_from = 0; start_recv_from < num_ues; start_recv_from++) { if (*cbuf_state[start_recv_from] == SSMP_BUF_MESSG) { volatile ssmp_msg_t* tmpm = cbuf->buf[start_recv_from]; memcpy64((volatile uint64_t*) msg, (const uint64_t*) tmpm, SSMP_CACHE_LINE_DW); tmpm->state = SSMP_BUF_EMPTY; msg->sender = cbuf->from[start_recv_from]; if (++start_recv_from == num_ues) { start_recv_from = 0; } return; } } } }
inline void ssmp_send_no_sync_platf(uint32_t to, volatile ssmp_msg_t* msg) { volatile ssmp_msg_t* tmpm = ssmp_send_buf[to]; memcpy64((volatile uint64_t*) tmpm, (const uint64_t*) msg, SSMP_CACHE_LINE_DW); tmpm->state = SSMP_BUF_MESSG; }
DWORD64 Wow64Local::GetLdrGetProcedureAddress() { DWORD ntSize = 0; DWORD64 modBase = GetNTDLL64(&ntSize); // Sanity check if(modBase == 0 || ntSize == 0) return 0; std::unique_ptr<uint8_t[]> buf(new uint8_t[ntSize]()); memcpy64((DWORD64)buf.get(), modBase, ntSize); IMAGE_NT_HEADERS64* inh = (IMAGE_NT_HEADERS64*)(buf.get() + ((IMAGE_DOS_HEADER*)buf.get())->e_lfanew); IMAGE_DATA_DIRECTORY& idd = inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; if(0 == idd.VirtualAddress) return 0; IMAGE_EXPORT_DIRECTORY* ied = (IMAGE_EXPORT_DIRECTORY*)(buf.get() + idd.VirtualAddress); DWORD* rvaTable = (DWORD*)(buf.get() + ied->AddressOfFunctions); WORD* ordTable = (WORD*)(buf.get() + ied->AddressOfNameOrdinals); DWORD* nameTable = (DWORD*)(buf.get() + ied->AddressOfNames); // lazy search, there is no need to use binsearch for just one function for(DWORD i = 0; i < ied->NumberOfFunctions; i++) { if(strcmp((char*)buf.get() + nameTable[i], "LdrGetProcedureAddress") != 0) continue; else return (DWORD64)(modBase + rvaTable[ordTable[i]]); } return 0; }
inline void ssmp_recv_from_platf(uint32_t from, volatile ssmp_msg_t* msg) { volatile ssmp_msg_t* tmpm = ssmp_recv_buf[from]; while(tmpm->state != SSMP_BUF_MESSG) { PAUSE; } memcpy64((volatile uint64_t*) msg, (const uint64_t*) tmpm, SSMP_CACHE_LINE_DW); tmpm->state = SSMP_BUF_EMPTY; }
inline void ssmp_send_platf(uint32_t to, volatile ssmp_msg_t* msg) { volatile ssmp_msg_t* tmpm = ssmp_send_buf[to]; while (tmpm->state != SSMP_BUF_EMPTY) { PAUSE; } memcpy64((volatile uint64_t*) tmpm, (const uint64_t*) msg, SSMP_CACHE_LINE_DW); tmpm->state = SSMP_BUF_MESSG; }
/******************************************************************** * モニタコマンド受信と実行. ******************************************************************** */ void ProcessIO(void) { // 返答パケットが空であること、かつ、 // 処理対象の受信データがある. if((ToPcRdy == 0) && (USBHandleBusy(USBGenericOutHandle)==0) ) { //受信データがあれば、受信データを受け取る. memcpy64((char*)&PacketFromPC,(char*)OUTPacket); //次の読み込みを発行する. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket ,USBGEN_EP_SIZE); PacketToPC.raw[0]=Cmd0; // CMD ECHOBACK //コマンドに対応する処理を呼び出す. if(Cmd0==HIDASP_PEEK) {cmd_peek();} // メモリー読み出し. else if(Cmd0==HIDASP_POKE) {cmd_poke();} // メモリー書き込み. else if(Cmd0==HIDASP_JMP) {cmd_exec();} // 実行. else if(Cmd0==HIDASP_TEST) {cmd_echo();} // 接続テスト. else if(Cmd0==HIDASP_GET_STRING){cmd_get_string();} else if(Cmd0==HIDASP_USER_CMD) {cmd_user_cmd();} else if(Cmd0==HIDASP_SET_MODE) {cmd_set_mode();} } // 必要なら、返答パケットをバルク転送(EP1)でホストPCに返却する. if( ToPcRdy ) { if(!USBHandleBusy(USBGenericInHandle)) { memcpy64(INPacket,(char*)&PacketToPC); USBGenericInHandle=USBGenWrite(USBGEN_EP_NUM,(BYTE*)INPacket,USBGEN_EP_SIZE); ToPcRdy = 0; if(poll_mode!=0) { if( USBHandleBusy(USBGenericOutHandle) ) {//コマンドが来ない限り送り続ける. make_report(); } } } } }
DWORD64 Wow64Local::getTEB64( TEB64& out ) { reg64 reg; reg.v = 0; X64_Start(); //R12 register should always contain pointer to TEB64 in WoW64 processes X64_Push(_R12); //below pop will pop QWORD from stack, as we're in x64 mode now __asm pop reg.dw[0] X64_End(); memcpy64((DWORD64)&out, reg.v, sizeof(out)); return reg.dw[0]; }
DWORD64 Wow64Local::GetTEB64(_TEB64& out) { UNREFERENCED_PARAMETER(out); reg64 reg; reg.v = 0; #ifdef _M_IX86 _asm { X64_Start(); //R12 register should always contain pointer to TEB64 in WoW64 processes X64_Push(_R12); //below pop will pop QWORD from stack, as we're in x64 mode now __asm pop reg.dw[0] X64_End(); } memcpy64((DWORD64)&out, reg.v, sizeof(out)); #endif return reg.v; }
inline void ssmp_recv_platf(ssmp_msg_t* msg) { uint32_t from; uint32_t num_ues = ssmp_num_ues_; while(1) { for (from = 0; from < num_ues; from++) { if (from != ssmp_id_ && ssmp_recv_buf[from]->state == SSMP_BUF_MESSG) { volatile ssmp_msg_t* tmpm = ssmp_recv_buf[from]; memcpy64((volatile uint64_t*) msg, (const uint64_t*) tmpm, SSMP_CACHE_LINE_DW); msg->sender = from; tmpm->state = SSMP_BUF_EMPTY; return; } } } }