Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

889 lines
23 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <errno.h>
  6. #include <malloc.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include "pperf.h"
  10. #include "..\pstat.h"
  11. extern HANDLE DriverHandle;
  12. extern UCHAR Buffer[];
  13. #define BufferSize 60000
  14. typedef struct NameList {
  15. struct NameList *Next;
  16. ULONG Parm;
  17. struct NameList *ChildList;
  18. PUCHAR Name;
  19. } NAME_LIST, *PNAME_LIST;
  20. PNAME_LIST DriverList;
  21. PNAME_LIST ActiveThunks;
  22. PNAME_LIST SourceModule, ImportModule;
  23. #define COMBOCMD(a,b) ((a << 16) | b)
  24. NTSTATUS
  25. openfile (
  26. IN PHANDLE filehandle,
  27. IN PUCHAR BasePath,
  28. IN PUCHAR Name
  29. );
  30. VOID
  31. readfile (
  32. HANDLE handle,
  33. ULONG offset,
  34. ULONG len,
  35. PVOID buffer
  36. );
  37. ULONG
  38. ConvertImportAddress (
  39. IN ULONG ImageRelativeAddress,
  40. IN ULONG PoolAddress,
  41. IN PIMAGE_SECTION_HEADER SectionHeader
  42. );
  43. VOID ThunkCreateDriverList (VOID);
  44. #define IMPADDRESS(a) ConvertImportAddress((ULONG)a, (ULONG)Buffer, &SectionHeader)
  45. ULONG HookThunk (PNAME_LIST, PNAME_LIST, PNAME_LIST);
  46. VOID SnapPrivateInfo (PDISPLAY_ITEM);
  47. VOID NameList2ComboBox (HWND hDlg, ULONG id, PNAME_LIST List);
  48. PNAME_LIST AddNameEntry (PNAME_LIST *head, PUCHAR name, ULONG Parm);
  49. VOID FreeNameList (PNAME_LIST List);
  50. PNAME_LIST GetComboSelection (HWND h, ULONG id);
  51. VOID NameList2ListBox (HWND hDlg, ULONG id, PNAME_LIST List);
  52. VOID loadimagedir (PUCHAR, ULONG, PIMAGE_SECTION_HEADER);
  53. VOID RemoveHook (HWND hDlg);
  54. VOID ClearAllHooks (HWND hDlg);
  55. VOID AddThunk (HWND hDlg);
  56. VOID loadexports (PNAME_LIST Driver, PNAME_LIST Item);
  57. //#define IDM_THUNK_LIST 301
  58. //#define IDM_THUNK_SOURCE 302
  59. //#define IDM_THUNK_IMPORT 303
  60. //#define IDM_THUNK_FUNCTION 304
  61. //#define IDM_THUNK_ADD 305
  62. //#define IDM_THUNK_REMOVE 306
  63. INT_PTR
  64. CALLBACK ThunkDlgProc(
  65. HWND hDlg,
  66. unsigned int message,
  67. WPARAM wParam,
  68. LPARAM lParam
  69. )
  70. {
  71. PNAME_LIST Item;
  72. switch (message) {
  73. case WM_INITDIALOG:
  74. SourceModule = NULL;
  75. ImportModule = NULL;
  76. ThunkCreateDriverList ();
  77. NameList2ComboBox (hDlg, IDM_THUNK_SOURCE, DriverList);
  78. NameList2ListBox (hDlg, IDM_THUNK_LIST, ActiveThunks);
  79. return (TRUE);
  80. case WM_COMMAND:
  81. switch(wParam) {
  82. //
  83. // end function
  84. //
  85. case COMBOCMD (CBN_SELCHANGE, IDM_THUNK_SOURCE):
  86. case COMBOCMD (CBN_SELCHANGE, IDM_THUNK_IMPORT):
  87. Item = GetComboSelection (hDlg, IDM_THUNK_SOURCE);
  88. if (Item && Item != SourceModule) {
  89. SourceModule = Item;
  90. NameList2ComboBox (hDlg, IDM_THUNK_IMPORT, Item->ChildList);
  91. }
  92. Item = GetComboSelection (hDlg, IDM_THUNK_IMPORT);
  93. if (Item && Item != ImportModule) {
  94. ImportModule = Item;
  95. NameList2ComboBox (hDlg, IDM_THUNK_FUNCTION, Item->ChildList);
  96. }
  97. break;
  98. case IDM_THUNK_REMOVE:
  99. RemoveHook (hDlg);
  100. break;
  101. case IDM_THUNK_CLEAR_ALL:
  102. ClearAllHooks (hDlg);
  103. break;
  104. case IDM_THUNK_ADD:
  105. AddThunk (hDlg);
  106. break;
  107. case IDOK:
  108. case IDCANCEL:
  109. //DlgThunkData (hDlg);
  110. FreeNameList (DriverList);
  111. DriverList = NULL;
  112. EndDialog(hDlg, DIALOG_SUCCESS);
  113. return (TRUE);
  114. }
  115. }
  116. return (FALSE);
  117. }
  118. VOID AddThunk (HWND hDlg)
  119. {
  120. PDISPLAY_ITEM pPerf;
  121. PNAME_LIST Item;
  122. ULONG id, i;
  123. PUCHAR p;
  124. HWND thunklist;
  125. int result;
  126. id = 0;
  127. Item = GetComboSelection (hDlg, IDM_THUNK_FUNCTION);
  128. if (Item && SourceModule && ImportModule) {
  129. id = HookThunk (SourceModule, ImportModule, Item);
  130. }
  131. if (!id) {
  132. MessageBox(hDlg,"Thunk was not hooked","Hook error",MB_OK);
  133. return;
  134. }
  135. pPerf = AllocateDisplayItem();
  136. //
  137. // build name (the hard way?)
  138. //
  139. pPerf->PerfName[sizeof(pPerf->PerfName) - 1] = 0;
  140. //
  141. // BogdanA 02/20/2002: this is ugly,
  142. // but I'll try to do the best as quickly as I can
  143. // since I do not own the code and do not intend to own it...
  144. //
  145. result = _snprintf(pPerf->PerfName,
  146. sizeof(pPerf->PerfName) - 1,
  147. "%s(%s",
  148. Item->Name, SourceModule->Name);
  149. if (result > 0 && sizeof(pPerf->PerfName) > result + strlen(ImportModule->Name) + 2) {
  150. //
  151. // We still have space in the buffer.
  152. // Check how much and do the pokey below
  153. //
  154. for (p=pPerf->PerfName; *p; p++) {
  155. if (*p == '.')
  156. *p = 0;
  157. }
  158. strcat (pPerf->PerfName, ">");
  159. strcat (pPerf->PerfName, ImportModule->Name);
  160. for (p=pPerf->PerfName; *p; p++) {
  161. if (*p == '.')
  162. *p = 0;
  163. }
  164. strcat (pPerf->PerfName, ")");
  165. }
  166. //
  167. // Add to thunk list
  168. //
  169. Item = malloc (sizeof (NAME_LIST));
  170. if (Item == NULL) {
  171. printf("Memory allocation failed.\n");
  172. exit(1);
  173. }
  174. Item->Name = _strdup (pPerf->PerfName);
  175. Item->Parm = (ULONG) pPerf;
  176. Item->ChildList = NULL;
  177. Item->Next = ActiveThunks;
  178. ActiveThunks = Item;
  179. pPerf->SnapParam2 = id;
  180. // bugbug
  181. NameList2ListBox (hDlg, IDM_THUNK_LIST, ActiveThunks);
  182. //
  183. // Add graph to windows
  184. //
  185. pPerf->SnapData = SnapPrivateInfo; // generic snap
  186. pPerf->SnapParam1 = OFFSET(PSTATS, ThunkCounters[id-1]);
  187. SetDisplayToTrue (pPerf, 99);
  188. RefitWindows(NULL, NULL);
  189. UpdateInternalStats ();
  190. pPerf->SnapData (pPerf);
  191. UpdateInternalStats ();
  192. pPerf->SnapData (pPerf);
  193. }
  194. VOID ClearAllHooks (HWND hDlg)
  195. {
  196. PDISPLAY_ITEM pPerf;
  197. IO_STATUS_BLOCK IOSB;
  198. ULONG id;
  199. PNAME_LIST Item;
  200. while (ActiveThunks) {
  201. pPerf = (PDISPLAY_ITEM) ActiveThunks->Parm;
  202. Item = ActiveThunks;
  203. ActiveThunks = ActiveThunks->Next;
  204. free (Item->Name);
  205. free (Item);
  206. id = pPerf->SnapParam2;
  207. SetDisplayToFalse (pPerf); // remove window
  208. FreeDisplayItem (pPerf);
  209. // notify driver
  210. if (DriverHandle) {
  211. NtDeviceIoControlFile(
  212. DriverHandle,
  213. (HANDLE) NULL, // event
  214. (PIO_APC_ROUTINE) NULL,
  215. (PVOID) NULL,
  216. &IOSB,
  217. PSTAT_REMOVE_HOOK,
  218. &id, // input buffer
  219. sizeof (ULONG),
  220. NULL, // output buffer
  221. 0
  222. );
  223. }
  224. }
  225. NameList2ListBox (hDlg, IDM_THUNK_LIST, ActiveThunks);
  226. RefitWindows (NULL, NULL);
  227. }
  228. VOID RemoveHook (HWND hDlg)
  229. {
  230. ULONG i, id;
  231. HWND ListBox;
  232. PNAME_LIST Item, *pp;
  233. PDISPLAY_ITEM pPerf;
  234. IO_STATUS_BLOCK IOSB;
  235. ListBox = GetDlgItem(hDlg, IDM_THUNK_LIST);
  236. i = SendMessage(ListBox, LB_GETCURSEL, 0, 0);
  237. if (i == -1) {
  238. return;
  239. }
  240. pPerf = (PDISPLAY_ITEM) SendMessage(ListBox, LB_GETITEMDATA, i, 0);
  241. Item = NULL;
  242. for (pp = &ActiveThunks; *pp; pp = &(*pp)->Next) {
  243. if ((*pp)->Parm == (ULONG)pPerf) {
  244. Item = *pp;
  245. *pp = (*pp)->Next; // remove from list
  246. break ;
  247. }
  248. }
  249. if (!Item) {
  250. return ;
  251. }
  252. free (Item->Name);
  253. free (Item);
  254. id = pPerf->SnapParam2;
  255. SetDisplayToFalse (pPerf); // remove window
  256. FreeDisplayItem (pPerf);
  257. // notify driver
  258. if (DriverHandle) {
  259. NtDeviceIoControlFile(
  260. DriverHandle,
  261. (HANDLE) NULL, // event
  262. (PIO_APC_ROUTINE) NULL,
  263. (PVOID) NULL,
  264. &IOSB,
  265. PSTAT_REMOVE_HOOK,
  266. &id, // input buffer
  267. sizeof (ULONG),
  268. NULL, // output buffer
  269. 0
  270. );
  271. }
  272. NameList2ListBox (hDlg, IDM_THUNK_LIST, ActiveThunks);
  273. RefitWindows (NULL, NULL);
  274. }
  275. VOID
  276. NameList2ListBox (HWND hDlg, ULONG id, PNAME_LIST List)
  277. {
  278. HWND ListBox;
  279. ULONG nIndex;
  280. ListBox = GetDlgItem(hDlg, id);
  281. SendMessage(ListBox, LB_RESETCONTENT, 0, 0);
  282. SendMessage(ListBox, LB_SETITEMDATA, 0L, 0L);
  283. while (List) {
  284. nIndex = SendMessage(ListBox, LB_ADDSTRING, 0, (LPARAM)List->Name);
  285. SendMessage(ListBox, LB_SETITEMDATA, nIndex, List->Parm);
  286. List = List->Next;
  287. }
  288. }
  289. VOID
  290. NameList2ComboBox (HWND hDlg, ULONG id, PNAME_LIST List)
  291. {
  292. HWND ComboList;
  293. ULONG nIndex;
  294. ComboList = GetDlgItem(hDlg, id);
  295. SendMessage(ComboList, CB_RESETCONTENT, 0, 0);
  296. SendMessage(ComboList, CB_SETITEMDATA, 0L, 0L);
  297. while (List) {
  298. nIndex = SendMessage(ComboList, CB_ADDSTRING, 0, (LPARAM)List->Name);
  299. SendMessage(ComboList, CB_SETITEMDATA, nIndex, (ULONG) List);
  300. List = List->Next;
  301. }
  302. SendMessage(ComboList, CB_SETCURSEL, 0, 0L);
  303. }
  304. PNAME_LIST
  305. GetComboSelection (HWND hDlg, ULONG id)
  306. {
  307. ULONG i;
  308. HWND ComboList;
  309. ComboList = GetDlgItem(hDlg, id);
  310. i = SendMessage(ComboList, CB_GETCURSEL, 0, 0);
  311. if (i == -1) {
  312. return NULL;
  313. }
  314. return (PNAME_LIST) SendMessage(ComboList, CB_GETITEMDATA, i, 0);
  315. }
  316. VOID
  317. FreeNameList (PNAME_LIST List)
  318. {
  319. PNAME_LIST p1;
  320. while (List) {
  321. if (List->ChildList)
  322. FreeNameList (List->ChildList);
  323. p1 = List->Next;
  324. free (List->Name);
  325. free (List);
  326. List = p1;
  327. }
  328. }
  329. ULONG
  330. HookThunk (PNAME_LIST HookSource, PNAME_LIST TargetModule, PNAME_LIST Function)
  331. {
  332. PNAME_LIST sourceModule;
  333. IO_STATUS_BLOCK IOSB;
  334. HOOKTHUNK HookData;
  335. ULONG TracerId;
  336. NTSTATUS status;
  337. if (! DriverHandle) {
  338. return 0;
  339. }
  340. TracerId = 0;
  341. for (sourceModule=DriverList; sourceModule; sourceModule = sourceModule->Next) {
  342. if (sourceModule->Parm == -1) {
  343. continue;
  344. }
  345. if (sourceModule->Parm != HookSource->Parm &&
  346. HookSource->Parm != -1) {
  347. continue;
  348. }
  349. HookData.SourceModule = sourceModule->Name;
  350. HookData.ImageBase = sourceModule->Parm;
  351. HookData.TargetModule = TargetModule->Name;
  352. HookData.Function = Function->Name;
  353. HookData.TracerId = TracerId;
  354. //
  355. // Ask driver to hook this thunk
  356. //
  357. status = NtDeviceIoControlFile(
  358. DriverHandle,
  359. (HANDLE) NULL, // event
  360. (PIO_APC_ROUTINE) NULL,
  361. (PVOID) NULL,
  362. &IOSB,
  363. PSTAT_HOOK_THUNK,
  364. &HookData, // input buffer
  365. sizeof (HookData),
  366. NULL, // output buffer
  367. 0
  368. );
  369. if (NT_SUCCESS(status)) {
  370. TracerId = HookData.TracerId;
  371. }
  372. }
  373. return TracerId;
  374. }
  375. VOID
  376. ThunkCreateDriverList ()
  377. {
  378. ULONG i;
  379. PRTL_PROCESS_MODULES Modules;
  380. PRTL_PROCESS_MODULE_INFORMATION Module;
  381. NTSTATUS status;
  382. PNAME_LIST Driver, Import, Item, AbortState;
  383. PIMAGE_IMPORT_DESCRIPTOR ImpDescriptor;
  384. IMAGE_SECTION_HEADER SectionHeader;
  385. ULONG ThunkAddr, ThunkData;
  386. //
  387. // Query driver list
  388. //
  389. status = NtQuerySystemInformation (
  390. SystemModuleInformation,
  391. Buffer,
  392. BufferSize,
  393. &i);
  394. if (!NT_SUCCESS(status)) {
  395. return;
  396. }
  397. //
  398. // Add drivers
  399. //
  400. Modules = (PRTL_PROCESS_MODULES) Buffer;
  401. Module = &Modules->Modules[ 0 ];
  402. for (i = 0; i < Modules->NumberOfModules; i++) {
  403. Driver = AddNameEntry (
  404. &DriverList,
  405. Module->FullPathName + Module->OffsetToFileName,
  406. (ULONG) Module->ImageBase
  407. );
  408. Module++;
  409. }
  410. //
  411. // Add imports for each driver
  412. //
  413. for (Driver = DriverList; Driver; Driver = Driver->Next) {
  414. try {
  415. //
  416. // Read in source image's headers
  417. //
  418. AbortState = Driver;
  419. loadimagedir (Driver->Name, IMAGE_DIRECTORY_ENTRY_IMPORT, &SectionHeader);
  420. //
  421. // Go through each import module
  422. //
  423. ImpDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) Buffer;
  424. while (ImpDescriptor->Characteristics) {
  425. AbortState = Driver;
  426. //
  427. // Add this import to driver's list
  428. //
  429. Import = AddNameEntry (
  430. &Driver->ChildList,
  431. (PUCHAR) IMPADDRESS(ImpDescriptor->Name),
  432. 1
  433. );
  434. AbortState = Import;
  435. //
  436. // Go through each function for the import module
  437. //
  438. ThunkAddr = IMPADDRESS (ImpDescriptor->OriginalFirstThunk);
  439. for (; ;) {
  440. ThunkData = (ULONG)((PIMAGE_THUNK_DATA) ThunkAddr)->u1.AddressOfData;
  441. if (ThunkData == 0) {
  442. // end of table
  443. break;
  444. }
  445. //
  446. // Add this function to import list
  447. //
  448. AddNameEntry (
  449. &Import->ChildList,
  450. ((PIMAGE_IMPORT_BY_NAME) IMPADDRESS(ThunkData))->Name,
  451. 0
  452. );
  453. // next thunk
  454. ThunkAddr += sizeof (IMAGE_THUNK_DATA);
  455. }
  456. // next import table
  457. ImpDescriptor++;
  458. }
  459. } except(EXCEPTION_EXECUTE_HANDLER) {
  460. AddNameEntry(&AbortState->ChildList, "* ERROR *", 1);
  461. }
  462. // next driver
  463. }
  464. //
  465. // Add "Any driver" selection
  466. //
  467. Driver = AddNameEntry(&DriverList, "*Any", (ULONG)-1);
  468. //
  469. // For child module list use complete driver list, which is
  470. // now on the next pointer of Driver.
  471. //
  472. for (Item = Driver->Next; Item; Item = Item->Next) {
  473. // bogus compiler - need to make a subfunction here to keep
  474. // the compiler happy
  475. loadexports (Driver, Item);
  476. }
  477. }
  478. VOID loadexports (PNAME_LIST Driver, PNAME_LIST Item)
  479. {
  480. IMAGE_SECTION_HEADER SectionHeader;
  481. PIMAGE_EXPORT_DIRECTORY ExpDirectory;
  482. PULONG ExpNameAddr;
  483. PNAME_LIST Import;
  484. ULONG i;
  485. try {
  486. loadimagedir (
  487. Item->Name,
  488. IMAGE_DIRECTORY_ENTRY_EXPORT,
  489. &SectionHeader
  490. );
  491. } except(EXCEPTION_EXECUTE_HANDLER) {
  492. return ;
  493. }
  494. Import = AddNameEntry (&Driver->ChildList, Item->Name, Item->Parm);
  495. try {
  496. ExpDirectory = (PIMAGE_EXPORT_DIRECTORY) Buffer;
  497. ExpNameAddr = (PULONG)IMPADDRESS (ExpDirectory->AddressOfNames);
  498. for (i=0; i < ExpDirectory->NumberOfNames; i++) {
  499. AddNameEntry (
  500. &Import->ChildList,
  501. (PUCHAR) IMPADDRESS(*ExpNameAddr),
  502. 0
  503. );
  504. ExpNameAddr++;
  505. }
  506. } except(EXCEPTION_EXECUTE_HANDLER) {
  507. AddNameEntry(&Import->ChildList, "* ERROR *", 1);
  508. }
  509. }
  510. VOID
  511. loadimagedir (
  512. IN PUCHAR filename,
  513. IN ULONG dirno,
  514. OUT PIMAGE_SECTION_HEADER SectionHeader
  515. )
  516. {
  517. HANDLE filehandle;
  518. ULONG i, j, Dir;
  519. NTSTATUS status;
  520. IMAGE_DOS_HEADER DosImageHeader;
  521. IMAGE_NT_HEADERS NtImageHeader;
  522. PIMAGE_SECTION_HEADER pSectionHeader;
  523. status = openfile (&filehandle, "\\SystemRoot\\", filename);
  524. if (!NT_SUCCESS(status)) {
  525. status = openfile (&filehandle, "\\SystemRoot\\System32\\", filename);
  526. }
  527. if (!NT_SUCCESS(status)) {
  528. status = openfile (&filehandle, "\\SystemRoot\\System32\\Drivers\\", filename);
  529. }
  530. if (!NT_SUCCESS(status)) {
  531. RtlRaiseStatus (1);
  532. }
  533. try {
  534. readfile (
  535. filehandle,
  536. 0,
  537. sizeof (DosImageHeader),
  538. (PVOID) &DosImageHeader
  539. );
  540. if (DosImageHeader.e_magic != IMAGE_DOS_SIGNATURE) {
  541. RtlRaiseStatus (1);
  542. }
  543. readfile (
  544. filehandle,
  545. DosImageHeader.e_lfanew,
  546. sizeof (NtImageHeader),
  547. (PVOID) &NtImageHeader
  548. );
  549. if (NtImageHeader.Signature != IMAGE_NT_SIGNATURE) {
  550. RtlRaiseStatus (1);
  551. }
  552. //
  553. // read in complete sections headers from image
  554. //
  555. i = NtImageHeader.FileHeader.NumberOfSections
  556. * sizeof (IMAGE_SECTION_HEADER);
  557. j = ((ULONG) IMAGE_FIRST_SECTION (&NtImageHeader)) -
  558. ((ULONG) &NtImageHeader) +
  559. DosImageHeader.e_lfanew;
  560. if (i > BufferSize) {
  561. RtlRaiseStatus (1);
  562. }
  563. readfile (
  564. filehandle,
  565. j, // file offset
  566. i, // length
  567. Buffer
  568. );
  569. //
  570. // Find section with import directory
  571. //
  572. Dir = NtImageHeader.OptionalHeader.DataDirectory[dirno].VirtualAddress;
  573. i = 0;
  574. pSectionHeader = (PIMAGE_SECTION_HEADER)Buffer;
  575. for (; ;) {
  576. if (i >= NtImageHeader.FileHeader.NumberOfSections) {
  577. RtlRaiseStatus (1);
  578. }
  579. if (pSectionHeader->VirtualAddress <= Dir &&
  580. pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData > Dir) {
  581. break;
  582. }
  583. i += 1;
  584. pSectionHeader += 1;
  585. }
  586. Dir -= pSectionHeader->VirtualAddress;
  587. pSectionHeader->VirtualAddress += Dir;
  588. pSectionHeader->PointerToRawData += Dir;
  589. pSectionHeader->SizeOfRawData -= Dir;
  590. *SectionHeader = *pSectionHeader;
  591. //
  592. // read in complete export section from image
  593. //
  594. if (SectionHeader->SizeOfRawData > BufferSize) {
  595. RtlRaiseStatus (1);
  596. }
  597. readfile (
  598. filehandle,
  599. SectionHeader->PointerToRawData,
  600. SectionHeader->SizeOfRawData,
  601. Buffer
  602. );
  603. } finally {
  604. //
  605. // Clean up
  606. //
  607. NtClose (filehandle);
  608. }
  609. }
  610. PNAME_LIST
  611. AddNameEntry (PNAME_LIST *head, PUCHAR name, ULONG Parm)
  612. {
  613. PNAME_LIST Entry;
  614. Entry = malloc (sizeof (NAME_LIST));
  615. if (Entry == NULL) {
  616. printf("Memory allocation failed.\n");
  617. exit(1);
  618. }
  619. Entry->Name = _strdup (name);
  620. if (Entry->Name == NULL) {
  621. printf("Memory allocation failed.\n");
  622. exit(1);
  623. }
  624. Entry->Parm = Parm;
  625. Entry->ChildList = NULL;
  626. if (Parm) {
  627. _strlwr (Entry->Name);
  628. }
  629. Entry->Next = *head;
  630. *head = Entry;
  631. return Entry;
  632. }
  633. NTSTATUS
  634. openfile (
  635. IN PHANDLE filehandle,
  636. IN PUCHAR BasePath,
  637. IN PUCHAR Name
  638. )
  639. {
  640. ANSI_STRING AscBasePath, AscName;
  641. UNICODE_STRING UniPathName, UniName;
  642. NTSTATUS status;
  643. OBJECT_ATTRIBUTES ObjA;
  644. IO_STATUS_BLOCK IOSB;
  645. UCHAR StringBuf[500];
  646. //
  647. // Build name
  648. //
  649. UniPathName.Buffer = (PWCHAR)StringBuf;
  650. UniPathName.Length = 0;
  651. UniPathName.MaximumLength = sizeof( StringBuf );
  652. RtlInitString(&AscBasePath, BasePath);
  653. status = RtlAnsiStringToUnicodeString( &UniPathName, &AscBasePath, FALSE );
  654. if (!NT_SUCCESS(status)) {
  655. return status;
  656. }
  657. RtlInitString(&AscName, Name);
  658. status = RtlAnsiStringToUnicodeString( &UniName, &AscName, TRUE );
  659. if (!NT_SUCCESS(status)) {
  660. return status;
  661. }
  662. status = RtlAppendUnicodeStringToString (&UniPathName, &UniName);
  663. if (!NT_SUCCESS(status)) {
  664. RtlFreeUnicodeString (&UniName);
  665. return status;
  666. }
  667. InitializeObjectAttributes(
  668. &ObjA,
  669. &UniPathName,
  670. OBJ_CASE_INSENSITIVE,
  671. 0,
  672. 0 );
  673. //
  674. // open file
  675. //
  676. status = NtOpenFile (
  677. filehandle, // return handle
  678. SYNCHRONIZE | FILE_READ_DATA, // desired access
  679. &ObjA, // Object
  680. &IOSB, // io status block
  681. FILE_SHARE_READ | FILE_SHARE_WRITE, // share access
  682. FILE_SYNCHRONOUS_IO_ALERT // open options
  683. );
  684. RtlFreeUnicodeString (&UniName);
  685. return status;
  686. }
  687. VOID
  688. readfile (
  689. HANDLE handle,
  690. ULONG offset,
  691. ULONG len,
  692. PVOID buffer
  693. )
  694. {
  695. NTSTATUS status;
  696. IO_STATUS_BLOCK iosb;
  697. LARGE_INTEGER foffset;
  698. foffset = RtlConvertUlongToLargeInteger(offset);
  699. status = NtReadFile (
  700. handle,
  701. NULL, // event
  702. NULL, // apc routine
  703. NULL, // apc context
  704. &iosb,
  705. buffer,
  706. len,
  707. &foffset,
  708. NULL
  709. );
  710. if (!NT_SUCCESS(status)) {
  711. RtlRaiseStatus (1);
  712. }
  713. }
  714. ULONG
  715. ConvertImportAddress (
  716. IN ULONG ImageRelativeAddress,
  717. IN ULONG PoolAddress,
  718. IN PIMAGE_SECTION_HEADER SectionHeader
  719. )
  720. {
  721. ULONG EffectiveAddress;
  722. EffectiveAddress = PoolAddress + ImageRelativeAddress -
  723. SectionHeader->VirtualAddress;
  724. if (EffectiveAddress < PoolAddress ||
  725. EffectiveAddress > PoolAddress + SectionHeader->SizeOfRawData) {
  726. RtlRaiseStatus (1);
  727. }
  728. return EffectiveAddress;
  729. }