Eingebettete Resource extrahieren

11/02/2008 23:42 link#1
Für die, die noch nicht wissen, wie sie eine eingebettete Resource extrahieren können, folgt hier ein kleiner Beispielquelltext:

Hier in Drexx-(M)asm:
Code:
SaveResource proc pName:DWORD, pType:DWORD, ID:DWORD
   add esp, -4
   push ebx
   push edi
   push esi
   push 0
   call GetModuleHandle
   mov edi, eax
   invoke FindResource, edi, ID, pType
   test eax, eax
   jz @f
   mov esi, eax
   invoke SizeofResource, edi, esi
   mov ebx, eax
   invoke LoadResource, edi, esi
   push eax
   call LockResource
   mov esi, eax
   invoke CreateFile, pName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
   cmp eax, INVALID_HANDLE_VALUE
   je @f
   push eax
   invoke WriteFile, eax, esi, ebx, [ebp - 4], 0
   pop eax
   invoke CloseHandle, eax
   mov eax, 1
   jmp @@e
@@:
   mov eax, 0
@@e:
   pop esi
   pop edi
   pop ebx
   ret
SaveResource endp
Hier in C:
Code:
int SaveResource(char *pName, int nID, char *pType) {
	DWORD dwbw;
	HGLOBAL hLoad;
	DWORD dwSize;
	void *lpData;
	HANDLE hFile;
	HMODULE hMod = GetModuleHandle(NULL);
	HRSRC hresource = FindResource(hMod, MAKEINTRESOURCE(nID), pType);
	if(!hresource) {
		return 0;
	}
	hLoad = LoadResource(hMod, hresource);
	lpData = LockResource(hLoad);
	dwSize = SizeofResource(hMod, hresource);
	hFile = CreateFile(pName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile == INVALID_HANDLE_VALUE) {
		return 0;
	}
	WriteFile(hFile, lpData, dwSize, &dwbw, NULL);
	CloseHandle(hFile);
	return (dwSize == dwbw);
}
Oder vielleicht ein wenig schöner (von der Formatierung her):
Code:
BOOL SaveResource(char *pName, int nID, char *pType) {
   DWORD dwbw;
   HMODULE hMod = GetModuleHandle(NULL);
   HRSRC hresource = FindResource(hMod, MAKEINTRESOURCE(nID), pType);
   if(hresource) {
      HGLOBAL hLoad = LoadResource(hMod, hresource);
      void *lpData = LockResource(hLoad);
      DWORD dwSize = SizeofResource(hMod, hresource);
      HANDLE hFile = CreateFile(pName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
      if(hFile == INVALID_HANDLE_VALUE) {
         return FALSE;
      }
      WriteFile(hFile, lpData, dwSize, &dwbw, NULL);
      CloseHandle(hFile);
      return (dwSize == dwbw);
   }
   return FALSE;
}
Die Resource sollte dann entweder z.B. im VisualStudio einfach in das ResourcenSkript importiert werden, oder man macht es manuell (myres.rc):
Quote:
//ID Type Path
100 DLL "extractme.dll"
Die Funktion ruft man dann so auf:
Code:
ResID equ 100
.data
  foo db "C:\extracted.dll", 0
  bar db "DLL", 0
.code
  invoke SaveResource, OFFSET foo, OFFSET bar, ResID
oder einfach:
Quote:
SaveResource("C:\\extracted.dll", "DLL", 100);