MapFile(void) : data(NULL), #ifdef HAVE_MMAP mmap_fd(-1) #elif defined(_WIN32) hFile(0), hFileMap(0) #endif { } ~MapFile(); bool open(const char *file_name, unsigned long file_size); inline gchar *begin(void) { return data; } private:
int _tmain(int argc, TCHAR* argv[]) { CoInitializeEx(NULL, COINIT_MULTITHREADED); try { if (argv[1] != 0 && argv[2] != 0 && argv[3] == 0) { CComPtr<IXMLDOMDocument2> xdoc; if (xdoc.CoCreateInstance(L"Msxml2.DOMDocument.6.0") != S_OK) throw MyMsgException(TEXT("Fail to create XML parser object!")); CComVariant strFileName; strFileName = SysAllocString( CT2CW(argv[1]) ); VARIANT_BOOL bIsSucc; xdoc->load(strFileName, &bIsSucc); if (bIsSucc != VARIANT_TRUE) throw MyMsgException(TEXT("Fail to load input file %s!"), argv[1]); CComPtr<IXMLDOMNode> xDllNameNode; CComBSTR strXPath; strXPath = L"/ImportLibrary/DllName"; xdoc->selectSingleNode(strXPath, &xDllNameNode); if (xDllNameNode == NULL) throw MyMsgException(TEXT("No DllName node!")); Sora::IImportLibraryBuilder* impBuilder; CComBSTR strDllName; xDllNameNode->get_text(&strDllName); CW2AEX<> cvtstrDllName(strDllName, CP_ACP); CComPtr<IXMLDOMNode> xAmd64Node; strXPath = L"/ImportLibrary/ArchAMD64"; xdoc->selectSingleNode(strXPath, &xAmd64Node); if (xAmd64Node == NULL) impBuilder = Sora::CreateX86ImpLibBuilder(cvtstrDllName, cvtstrDllName); else impBuilder = Sora::CreateX64ImpLibBuilder(cvtstrDllName, cvtstrDllName); strXPath = L"/ImportLibrary/Import"; CComPtr<IXMLDOMNodeList> xImportNodes; if (xdoc->selectNodes(strXPath, &xImportNodes) != S_OK) throw MyMsgException(TEXT("No Import nodes found!")); for(;;) { CComPtr<IXMLDOMNode> xImportNode; if (xImportNodes->nextNode(&xImportNode) != S_OK) break; CComPtr<IXMLDOMNode> xLinkNameNode, xStubNameNode, xImportNameNode, xImportOrdinalNode; CComBSTR strLinkName, strStubName, strImportName, strImportOrdinal; strXPath = L"./LinkName"; if (xImportNode->selectSingleNode(strXPath, &xLinkNameNode) != S_OK) throw MyMsgException(TEXT("No LinkName Node!")); strXPath = L"./StubName"; xImportNode->selectSingleNode(strXPath, &xStubNameNode); //if no stubname node found, will not generate callstub xLinkNameNode->get_text(&strLinkName); if (xStubNameNode != NULL) xStubNameNode->get_text(&strStubName); HRESULT selectImportName; HRESULT selectOrdinal; strXPath = L"./ImportName"; selectImportName = xImportNode->selectSingleNode(strXPath, &xImportNameNode); strXPath = L"./Ordinal"; selectOrdinal = xImportNode->selectSingleNode(strXPath, &xImportOrdinalNode); int nOrdinal = 0; if (selectImportName == S_OK || selectOrdinal == S_OK) { if (selectImportName == S_OK) xImportNameNode->get_text(&strImportName); if (selectOrdinal == S_OK) { xImportOrdinalNode->get_text(&strImportOrdinal); LPCWSTR pszImportOrdinal = strImportOrdinal; while(*pszImportOrdinal != 0) { nOrdinal *= 10; nOrdinal += *pszImportOrdinal - L'0'; ++pszImportOrdinal; } } if (selectImportName == S_OK && selectOrdinal == S_OK) { impBuilder->AddImportFunctionByNameWithHint( CW2AEX<>(strLinkName, CP_UTF8), CW2AEX<>(strStubName, CP_UTF8), CW2AEX<>(strImportName, CP_UTF8), nOrdinal ); } else if (selectImportName == S_OK) { impBuilder->AddImportFunctionByName( CW2AEX<>(strLinkName, CP_UTF8), CW2AEX<>(strStubName, CP_UTF8), CW2AEX<>(strImportName, CP_UTF8) ); } else if (selectOrdinal == S_OK) { impBuilder->AddImportFunctionByOrdinal( CW2AEX<>(strLinkName, CP_UTF8), CW2AEX<>(strStubName, CP_UTF8), nOrdinal ); } } else { throw MyMsgException(TEXT("No ImportName or Ordinal Node!")); } } //save file impBuilder->Build(); int nFileSize = impBuilder->GetDataLength(); CHandle hFile( CreateFile(argv[2], GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL) ); if ( (HANDLE)hFile == INVALID_HANDLE_VALUE ) throw MyMsgException(TEXT("Fail to create library File %s!"), argv[2]); if (SetFilePointer(hFile, nFileSize, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) if (GetLastError() != 0) throw MyMsgException(TEXT("Can't allocate disk space for output file!")); if (SetEndOfFile(hFile) == FALSE) throw MyMsgException(TEXT("Can't allocate disk space for output file!")); CHandle hFileMap( CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, nFileSize, 0) ); if ((HANDLE)hFileMap == NULL) throw MyMsgException(TEXT("Can't map output file for writing!")); LPVOID pFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0); if (pFile == 0) throw MyMsgException(TEXT("Can't map output file for writing!")); impBuilder->GetRawData((PBYTE)pFile); impBuilder->Dispose(); UnmapViewOfFile(pFile); } else { fprintf(stdout, "%s", "Make import library from XML\n" "using: MakeImpLib <input xml> <output lib>\n" "\n" "XML Sample\n" "<ImportLibrary>\n" " <!-- <ArchAMD64 /> -->\n" " <!-- If no ArchAMD64 node, it creates i386 import library -->\n" " <DllName>Kernel32.dll</DllName>\n" " <Import>\n" " <LinkName>__imp__SleepEx@8</LinkName>\n" " <!-- StubName can be removed, so no call stub will generated -->\n" " <StubName>_SleepEx@8</StubName>\n" " <!-- For Ordinal and ImportName, you can use either or both -->\n" " <!-- When use both, it's import by name and ordinal works as hint -->\n" " <!-- In most case only ImportName is used, that's enough -->\n" " <!-- But you can't strip both -->\n" " <Ordinal>1208</Ordinal>\n" " <ImportName>SleepEx</ImportName>\n" " </Import>\n" " <Import>\n" " <LinkName>__imp__WaitForSingleObject@8</LinkName>\n" " <ImportName>WaitForSingleObject</ImportName>\n" " </Import>\n" "</ImportLibrary>\n" "\n" "<?xml version=\"1.0\" encoding=\"UTF-8\"?> is needed " "for filename or function other than English letters.\n" ); } } catch (MyMsgException e) { fprintf(stderr, CT2CA(e.fmt), CT2CA(e.msg)); } CoUninitialize(); }
/******************************************************************************* * * 函 数 名 : GetPEFileBit * 功能描述 : 取得可执行文件的位数 * 参数列表 : pPEFilePath -- pe文件路径 * 说 明 : 读pe文件的头进内存,再调用GetBitByPEHeader去判断 * 返回结果 : 返回当前进程位数 * *******************************************************************************/ ULONG GetPEFileBit(__in_z CONST PTCHAR pPEFilePath) { ULONG uResult(0) ; HANDLE hFile(INVALID_HANDLE_VALUE) ; HANDLE hFileMap(NULL) ; LPVOID pAddr(NULL) ; __try { if (NULL == pPEFilePath) { OutputDebugString(TEXT("GetPEFileBit pPEFilePath can't NULL!\r\n")) ; __leave ; } if(FALSE == PathFileExists(pPEFilePath)) { OutputDebugString(TEXT("The file does not exist!\r\n")) ; __leave ; } hFile = CreateFile(pPEFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ; if (INVALID_HANDLE_VALUE == hFile) { OutputErrorInformation(TEXT("GetPEFileBit"), TEXT("CreateFile")) ; __leave ; } hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL) ; if (NULL == hFile) { OutputErrorInformation(TEXT("GetPEFileBit"), TEXT("CreateFileMapping")) ; __leave ; } pAddr = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) ; if (NULL == pAddr) { OutputErrorInformation(TEXT("GetPEFileBit"), TEXT("MapViewOfFile")) ; __leave ; } uResult = GetBitByPEHeader(pAddr, GetFileSize(hFile, NULL)) ; } __finally { if (NULL != pAddr) { UnmapViewOfFile(pAddr) ; pAddr = NULL ; } if (NULL != hFileMap) { CloseHandle(hFileMap) ; hFileMap = NULL ; } if (INVALID_HANDLE_VALUE != hFile) { CloseHandle(hFile) ; hFile = INVALID_HANDLE_VALUE ; } } return uResult ; }
UINT ExtractIcons::_ExtractFromExe( HANDLE hFile, int iconIndex, int cxIconSize, int cyIconSize, HICON *phicon, UINT *piconid, UINT maxIcons, UINT flags ) { DWORD fileLen = GetFileSize( hFile, NULL ); SmartHANDLE hFileMap( CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ) ); if( hFileMap == NULL ) return 0; SmartFileMapping pFile( MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) ); if( pFile == NULL ) return 0; IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)(void*)pFile; if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ) return 0; if( pDosHeader->e_lfanew <= 0 ) return 0; if( DWORD(pDosHeader->e_lfanew) >= fileLen ) return 0; void* pRes = _GetResourceTable( pDosHeader ); if( pRes == NULL) return 0; // cant find the resource DWORD cbSize = 0; if( phicon == NULL ) { // we want the count int count = _FindResourceCount( pRes, (INT_PTR)RT_GROUP_ICON ); return count; } UINT res = 0; while( res < maxIcons ) { // find the icon dir for this icon. NEWHEADER* pIconDir = (NEWHEADER*)_FindResource( pDosHeader, pRes, iconIndex, (INT_PTR)RT_GROUP_ICON, &cbSize ); if( pIconDir == NULL ) return res; if( pIconDir->Reserved != 0 || pIconDir->ResType != RES_ICON ) // 1 == iconType { _ASSERT( 0 ); return res; } int idIcon = LookupIconIdFromDirectoryEx( (LPBYTE)pIconDir, TRUE, cxIconSize, cyIconSize, flags ); void* pIcon = _FindResource( pDosHeader, pRes, -idIcon, (INT_PTR)RT_ICON, &cbSize ); if( pIcon == NULL ) return res; if( (((LPBITMAPINFOHEADER)pIcon)->biSize != sizeof(BITMAPINFOHEADER)) && (((LPBITMAPINFOHEADER)pIcon)->biSize != sizeof(BITMAPCOREHEADER)) ) { _ASSERT( 0 ); return res; } if( piconid ) piconid[res] = idIcon; phicon[res] = CreateIconFromResourceEx( (LPBYTE)pIcon, cbSize, TRUE, VER30, cxIconSize, cyIconSize, flags ); res++; iconIndex++; // next icon index } return res; }