Merge pull request #2 from vyvojar/master
[WindowsD.git] / service.c
blobbf660a64de852a5a267f8b9b411c68e63ed05fb6
1 #include <windows.h>
2 #include <winternl.h>
3 #include <ntstatus.h>
4 #include <stdio.h>
5 #include "defs.h"
6 #include "ntcruft.h"
7 #include "wind.h"
9 static void *patch_iat(HMODULE hostexe, char *dll, char *func, void *to)
11 PIMAGE_DOS_HEADER mz = (void*)hostexe;
12 PIMAGE_IMPORT_DESCRIPTOR imports;
14 imports = RVA2PTR(mz, ((PIMAGE_NT_HEADERS)RVA2PTR(mz, mz->e_lfanew))->
15 OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
17 for (int i = 0; imports[i].Characteristics; i++) {
18 PIMAGE_THUNK_DATA t1, t2;
19 PIMAGE_IMPORT_BY_NAME import;
21 char *dlln = RVA2PTR(mz, imports[i].Name);
22 DBG("checking dll %s", dlln);
23 if (_stricmp(dll, dlln))
24 continue;
26 t1 = RVA2PTR(mz, imports[i].FirstThunk);
27 t2 = RVA2PTR(mz, imports[i].OriginalFirstThunk);
29 for (; t2->u1.Function; t1++, t2++) {
30 void *oldfn;
31 DWORD oldp;
32 MEMORY_BASIC_INFORMATION vmi;
34 if (t2->u1.Ordinal & IMAGE_ORDINAL_FLAG)
35 continue;
37 import = RVA2PTR(mz, t2->u1.AddressOfData);
38 if (strcmp(func, (char*)import->Name))
39 continue;
41 oldfn = (void*)t1->u1.Function;
42 DBG("oldfn is %p\n",oldfn);
44 VirtualQuery(t1, &vmi, sizeof(vmi));
45 if (!VirtualProtect(vmi.BaseAddress, vmi.RegionSize, PAGE_READWRITE, &oldp)) {
46 DBG("VirtualProtect failed with %d", (int)GetLastError());
47 return NULL;
49 t1->u1.Function = (ULONG_PTR)to;
50 VirtualProtect(vmi.BaseAddress, vmi.RegionSize, oldp, &oldp);
51 return oldfn;
54 DBG("symbol %s@%s not found in imports", func, dll);
55 return NULL;
58 static NTSTATUS insmod(PUNICODE_STRING svc)
60 return wind_insmod(svc->Buffer);
63 BOOL APIENTRY ENTRY(dll_main)(HANDLE hModule, DWORD code, LPVOID res)
65 static int done = 0;
66 if (code != DLL_PROCESS_ATTACH || done)
67 return TRUE;
68 done = 1;
69 DBG("inside dll!");
70 patch_iat(GetModuleHandle(NULL), "ntdll.dll", "NtLoadDriver", insmod);
71 return TRUE;