/*---------------------------------------------------------- あやしいコード ----------------------------------------------------------*/ char* SPShiori::LoadModuleAndModifySpecificDLL(JString &filename) { if ( stricmp(m_ShioriFilename.Buffer(),"first.dll") == 0 ) { //FIRST //MATERIA内からDLL切り出し JString tmpFile(filename); if ( tmpFile[tmpFile.Length() - 1] == '\\' ) { tmpFile.RemoveLast(); } char *pEndPoint = tmpFile.Buffer() + 3; //"C:\" if ( tmpFile[0] == '\\' && tmpFile[1] == '\\' ) { //UNC char *pServerName = (char*)_mbschr((unsigned char*)tmpFile.Buffer() + 2,'\\'); if ( pServerName ) { pEndPoint = pServerName; } } //ディレクトリを上までさかのぼってmateria.exeをさがす JString fileMateria; char *pBS = (char*)_mbsrchr((unsigned char*)tmpFile.Buffer(),'\\'); if ( pBS ) { *pBS = 0; DWORD fileAttr = 0xFFFFFFFFU; while ( TRUE ) { fileMateria = tmpFile.Buffer(); //bufferでないとだめ fileMateria += "\\materia.exe"; fileAttr = ::GetFileAttributes(fileMateria.Buffer()); if ( fileAttr != 0xFFFFFFFF ) { break; } pBS = (char*)_mbsrchr((unsigned char*)tmpFile.Buffer(),'\\'); if ( ! pBS ) { break; } if ( pBS <= pEndPoint ) { break; } *pBS = 0; } if ( fileAttr == 0xFFFFFFFFU ) { fileMateria.Clear(); } } if ( fileMateria.Length() == 0 ) { return NULL; } HANDLE fMateria = CreateFile(fileMateria.Buffer(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if ( fMateria == INVALID_HANDLE_VALUE ) { return NULL; } FILETIME tmMateria; GetFileTime(fMateria,NULL,NULL,&tmMateria); CloseHandle(fMateria); BOOL mustExtractDLL = TRUE; JString filename3(m_Path); filename3 += "mai.dll"; HANDLE fMai = CreateFile(filename3.Buffer(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if ( fMai != INVALID_HANDLE_VALUE ) { FILETIME tmMai; GetFileTime(fMai,NULL,NULL,&tmMai); if ( tmMai.dwHighDateTime == tmMateria.dwHighDateTime && tmMai.dwLowDateTime == tmMateria.dwLowDateTime ) { mustExtractDLL = FALSE; } CloseHandle(fMai); } if ( mustExtractDLL ) { HINSTANCE hInst = LoadLibrary(fileMateria.Buffer()); if ( ! hInst ) { return NULL; } char *pFNArray[] = {"mai.dll","sayuri.dll"}; int resIDArray[] = {102,104}; JString dllName; for ( UINT i = 0 ; i < (sizeof(resIDArray) / sizeof(int)) ; ++i ) { HRSRC hResMaiDLL = FindResource(hInst,MAKEINTRESOURCE(resIDArray[i]),"DLL"); if ( ! hResMaiDLL ) { return NULL; } dllName = m_Path; dllName += pFNArray[i]; HGLOBAL hDataMaiDLL = LoadResource(hInst,hResMaiDLL); DWORD len = SizeofResource(hInst,hResMaiDLL); LPVOID data = LockResource(hDataMaiDLL); fMai = CreateFile(dllName.Buffer(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); DWORD writtenSize; ::WriteFile(fMai,data,len,&writtenSize,NULL); ::SetFileTime(fMai,&tmMateria,&tmMateria,&tmMateria); //更新日時をMATERIAとあわせる ::CloseHandle(fMai); } FreeLibrary(hInst); } m_hModule = ::LoadLibrary(filename.Buffer()); if ( ! m_hModule ) { return NULL; } //****ここから怪しい部分の本番!****// //HMODULE = DLLが読み込まれた先頭アドレス //DOSスタブ char *pFile = (char*)m_hModule; IMAGE_DOS_HEADER *pHeaderDOS = (IMAGE_DOS_HEADER*)pFile; pFile += pHeaderDOS->e_lfanew; //イメージ実体 materia.exeという文字列はコードセクション内 IMAGE_NT_HEADERS32 *pHeader = (IMAGE_NT_HEADERS32*)pFile; pFile += pHeader->OptionalHeader.BaseOfCode; char *pEnd = pFile + pHeader->OptionalHeader.SizeOfCode - 11; //"materia.exe" while ( pFile < pEnd ) { if ( memcmp(pFile,"materia.exe",11) == 0 && *((DWORD*)(pFile - 4)) == 11 ) { //先頭4バイトは文字列長 DWORD oldProtectFlag,tmp; //強制的にssp.exeに書き換え HANDLE hProcess = ::GetCurrentProcess(); VirtualProtectEx(hProcess,pFile - 4,15,PAGE_READWRITE,&oldProtectFlag); memcpy(pFile,"ssp.exe\0\0\0\0",11); *((DWORD*)(pFile - 4)) = 7; VirtualProtectEx(hProcess,pFile - 4,15,oldProtectFlag,&tmp); break; } ++pFile; } m_pGhost->m_dontShioriCache = TRUE; return pFile; } m_hModule = ::LoadLibrary(filename.Buffer()); return NULL; }