/* Zu Fuß Ressourcen lesen - für den Treiber */
#include <windows.h>
#include <stdio.h>
#define elemof(x) (sizeof(x)/sizeof(*(x)))
// Bonus, nicht für Treiber
static void LocateResource(PBYTE a) {
PIMAGE_NT_HEADERS h;
PIMAGE_RESOURCE_DIRECTORY r;
PIMAGE_RESOURCE_DIRECTORY_ENTRY e;
PIMAGE_SECTION_HEADER ish;
PBYTE r0;
DWORD i,diff;
if (*(PWORD)a!=IMAGE_DOS_SIGNATURE) return;
h=(PIMAGE_NT_HEADERS)(a+*(PDWORD)(a+0x3C));
if (h->Signature!=IMAGE_NT_SIGNATURE) return;
ish=(PIMAGE_SECTION_HEADER)((PBYTE)&(h->OptionalHeader)+h->FileHeader.SizeOfOptionalHeader);
for (i=h->FileHeader.NumberOfSections; i; i--) {
if (lstrcmpiA((LPCSTR)ish->Name,".rsrc")==0) goto found;
ish++;
}
return;
found:
r0=a+ish->PointerToRawData;
diff=ish->VirtualAddress-ish->PointerToRawData;
// +h->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE/*2 - Offset 112*/].VirtualAddress
// -h->OptionalHeader.SizeOfHeaders;
r=(PIMAGE_RESOURCE_DIRECTORY)r0;
e=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(r+1);
for (i=r->NumberOfIdEntries; i; i--) {
if (e->Id==(WORD)RT_RCDATA) {
r=(PIMAGE_RESOURCE_DIRECTORY)(r0+e->OffsetToDirectory);
e=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(r+1);
for (i=r->NumberOfIdEntries; i; i--) {
if (e->Id==100) {
r=(PIMAGE_RESOURCE_DIRECTORY)(r0+e->OffsetToDirectory);
e=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(r+1);
for (i=r->NumberOfIdEntries; i; i--) {
if (true) { // egal welche Sprache
PIMAGE_RESOURCE_DATA_ENTRY e2=(PIMAGE_RESOURCE_DATA_ENTRY)(r0+e->OffsetToData);
r0=a+e2->OffsetToData-diff;
printf("%x %x\n",r0-a, diff);
printf("%d %d\n",((PWORD)r0)[0],((PWORD)r0)[1]);
break;
}
e++;
}
break;
}
e++;
}
break;
}
e++;
}
}
/************************************
* Ab hier der Kode für den Treiber *
************************************/
static void _stdcall ReadAt(HFILE h, DWORD pos, PVOID w, DWORD l) {
_llseek(h,pos,0); _lread(h,w,l); // ZwReadFile()
}
PBYTE _stdcall LoadRCData(HFILE h, WORD id, DWORD*len) {
// Datei-I/O im Kernel-Mode - NUR RCDATA - NUR numerische IDs
// Der Aufrufer muss den gelieferten Speicher-Zeiger freigeben.
WORD w,w1,w2;
DWORD l,p,p0,i;
PBYTE ret;
ReadAt(h,0,&w,2); if (w!=/*IMAGE_DOS_SIGNATURE*/'ZM') return NULL;
ReadAt(h,0x3C,&p,4);
ReadAt(h,p,&l,4); if (l!=/*IMAGE_NT_SIGNATURE*/'EP') return NULL;
ReadAt(h,p+6,&w1,2); // NumberOfSections
ReadAt(h,p+0x14,&w2,2); // SizeOfOptionalHeader
p+=0x18+w2;
for (i=w1; i; i--) {
char buf[6];
ReadAt(h,p,buf,6);
// if (lstrcmpiA(buf,".rsrc")==0) goto f0; // RtlCompare...
if (*(PDWORD)buf=='rsr.' && ((PWORD)buf)[2]=='c') goto f0; // schneller
// if (*(__int64*)buf&0xFFFFFFFFFFFF=='crsr.' goto f0 // für x64-Architektur
p+=0x28; // sizeof(IMAGE_SECTION_HEADER)
}
return NULL;
f0:
ReadAt(h,p+0x0C,&l,4); // VirtualAddress
ReadAt(h,p+0x14,&p,4); // PointerToRawData
l-=p0=p; // Differenz (wichtig!!)
ReadAt(h,p+0x0C,&i,4); // NumberOfEntries
w1=LOWORD(i); w2=HIWORD(i);
p+=0x10+8*w1; // NumberOfNamedEntries übergehen
for (i=w2; i; i--) { // Suche RCDATA-Ressourcen
ReadAt(h,p,&w,2);
if (w==(WORD)RT_RCDATA/*10*/) goto f1;
p+=8; // sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)
}
return NULL;
f1:
ReadAt(h,p+4,&i,4);
p=p0+(i&0x7FFFFFFF);
ReadAt(h,p+0x0C,&i,4); // nochmal dasselbe
w1=LOWORD(i); w2=HIWORD(i);
p+=0x10+8*w1;
for (i=w2; i; i--) { // Suche Ressource mit passender ID
ReadAt(h,p,&w,2);
if (w==id) goto f2;
p+=8;
}
return NULL;
f2:
ReadAt(h,p+4,&i,4);
p=p0+(i&0x7FFFFFFF);
ReadAt(h,p+0x14,&i,4); // erster (einziger) Eintrag
p=p0+i;
ReadAt(h,p,&p0,4);
p0-=l;
ReadAt(h,p+4,&l,4);
ret = new BYTE[l]; // ExAllocatePoolWithTag()
if (!ret) return NULL;
ReadAt(h,p0,ret,l);
if (len) *len=l;
return ret;
}
/************************************
* Ende Treiberkode. User-Mode-Demo *
************************************/
// Einfaches Hex/ASCII-Dump
static void hdump(PBYTE a, DWORD l) {
for (DWORD j=0; j<l; j+=16) {
printf("%04X",j);
DWORD i;
for (i=0; i<16; i++) {
if (j+i>=l) break;
printf(" %02X",a[j+i]);
}
for (; i<17; i++) printf(" ");
for (i=0; i<16; i++) {
if (j+i>=l) break;
printf("%c",isprint(a[j+i])||(char)a[j+i]<0?a[j+i]:'.');
}
printf("\n");
}
}
void mainCRTStartup(void) {
HANDLE hFile,hMapped;
HFILE f;
PBYTE lpBaseAddress;
TCHAR ExeFileName[MAX_PATH];
GetModuleFileName(0,ExeFileName,elemof(ExeFileName));
// Erste Methode: Datei laden (perfekt für Treiber)
f=_lopen(ExeFileName,0); // ZwCreateFile()
if (f) {
PWORD x;
DWORD len;
x=(PWORD)LoadRCData(f,100,&len);
if (x) {
hdump((PBYTE)x,len);
delete[] x; // ExFreePool()
}
_lclose(f); // ZwClose()
}
// Zweite Methode: Datei einblenden (weiß nicht wie das für Treiber geht)
hFile=CreateFile(ExeFileName, GENERIC_READ,0,
NULL,OPEN_EXISTING,0,NULL);
if (hFile!=INVALID_HANDLE_VALUE) {
hMapped=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if (hMapped) {
lpBaseAddress=(PBYTE)MapViewOfFile(hMapped,FILE_MAP_READ,0,0,0);
if (lpBaseAddress) {
LocateResource(lpBaseAddress);
UnmapViewOfFile(lpBaseAddress);
}
CloseHandle(hMapped);
}
CloseHandle(hFile);
}
}
Detected encoding: ANSI (CP1252) | 4
|
|