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.

384 lines
9.0 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include "apimon.h"
  4. HANDLE ApiMonMutex;
  5. PVOID MemPtr;
  6. PDLL_INFO DllList;
  7. LPDWORD ApiCounter;
  8. LPDWORD ApiTraceEnabled;
  9. LPDWORD ApiTimingEnabled;
  10. LPDWORD FastCounterAvail;
  11. LPDWORD ApiOffset;
  12. LPDWORD ApiStrings;
  13. LPDWORD ApiCount;
  14. LPSTR TraceFileName;
  15. PDLL_INFO
  16. AddDllToList(
  17. HANDLE hProcess,
  18. ULONG DllAddr,
  19. LPSTR DllName,
  20. ULONG DllSize
  21. );
  22. ULONG
  23. AddApisForDll(
  24. HANDLE hProcess,
  25. PDLL_INFO DllInfo
  26. );
  27. int _cdecl
  28. main(
  29. int argc,
  30. char *argv[]
  31. )
  32. {
  33. HANDLE hMap;
  34. PDLL_INFO DllInfo;
  35. hMap = CreateFileMapping(
  36. (HANDLE)0xffffffff,
  37. NULL,
  38. PAGE_READWRITE | SEC_COMMIT,
  39. 0,
  40. MAX_MEM_ALLOC,
  41. "ApiWatch"
  42. );
  43. if (!hMap) {
  44. return 1;
  45. }
  46. MemPtr = (PUCHAR)MapViewOfFile(
  47. hMap,
  48. FILE_MAP_WRITE,
  49. 0,
  50. 0,
  51. 0
  52. );
  53. if (!MemPtr) {
  54. return 1;
  55. }
  56. ApiMonMutex = CreateMutex( NULL, FALSE, "ApiMonMutex" );
  57. if (!ApiMonMutex) {
  58. return FALSE;
  59. }
  60. ApiCounter = (LPDWORD)MemPtr + 0;
  61. ApiTraceEnabled = (LPDWORD)MemPtr + 1;
  62. ApiTimingEnabled = (LPDWORD)MemPtr + 2;
  63. FastCounterAvail = (LPDWORD)MemPtr + 3;
  64. ApiOffset = (LPDWORD)MemPtr + 4;
  65. ApiStrings = (LPDWORD)MemPtr + 5;
  66. ApiCount = (LPDWORD)MemPtr + 6;
  67. TraceFileName = (LPSTR)((LPDWORD)MemPtr + 7);
  68. DllList = (PDLL_INFO)((LPDWORD)MemPtr + 8 + MAX_PATH);
  69. *ApiOffset = (MAX_DLLS * sizeof(DLL_INFO)) + ((ULONG)DllList - (ULONG)MemPtr);
  70. *ApiStrings = (MAX_APIS * sizeof(API_INFO)) + *ApiOffset;
  71. #if 0
  72. DllInfo = AddDllToList( NULL,
  73. HANDLE hProcess,
  74. ULONG DllAddr,
  75. LPSTR DllName,
  76. ULONG DllSize
  77. );
  78. #endif
  79. LoadLibrary( "apidll.dll" );
  80. return 0;
  81. }
  82. BOOL
  83. ReadMemory(
  84. HANDLE hProcess,
  85. PVOID Address,
  86. PVOID Buffer,
  87. ULONG Length
  88. )
  89. {
  90. CopyMemory( Buffer, Address, Length );
  91. return TRUE;
  92. }
  93. PDLL_INFO
  94. FindDllByAddress(
  95. ULONG DllAddr
  96. )
  97. {
  98. ULONG i;
  99. for (i=0; i<MAX_DLLS; i++) {
  100. if (DllList[i].BaseAddress == DllAddr) {
  101. return &DllList[i];
  102. }
  103. }
  104. return NULL;
  105. }
  106. PDLL_INFO
  107. FindDllByName(
  108. LPSTR DllName
  109. )
  110. {
  111. ULONG i;
  112. for (i=0; i<MAX_DLLS; i++) {
  113. if (DllList[i].Name[0] &&
  114. _stricmp( DllList[i].Name, DllName ) == 0) {
  115. return &DllList[i];
  116. }
  117. }
  118. return NULL;
  119. }
  120. PDLL_INFO
  121. FindAvailDll(
  122. VOID
  123. )
  124. {
  125. ULONG i;
  126. for (i=0; i<MAX_DLLS; i++) {
  127. if (!DllList[i].BaseAddress) {
  128. return &DllList[i];
  129. }
  130. }
  131. return NULL;
  132. }
  133. PDLL_INFO
  134. AddDllToList(
  135. HANDLE hProcess,
  136. ULONG DllAddr,
  137. LPSTR DllName,
  138. ULONG DllSize
  139. )
  140. {
  141. IMAGE_DOS_HEADER dh;
  142. IMAGE_NT_HEADERS nh;
  143. ULONG i;
  144. PDLL_INFO DllInfo;
  145. //
  146. // first look to see if the dll is already in the list
  147. //
  148. DllInfo = FindDllByAddress( DllAddr );
  149. if (!DllSize) {
  150. //
  151. // read the pe image headers to get the image size
  152. //
  153. if (!ReadMemory(
  154. hProcess,
  155. (PVOID) DllAddr,
  156. &dh,
  157. sizeof(dh)
  158. )) {
  159. return NULL;
  160. }
  161. if (dh.e_magic == IMAGE_DOS_SIGNATURE) {
  162. if (!ReadMemory(
  163. hProcess,
  164. (PVOID)(DllAddr + dh.e_lfanew),
  165. &nh,
  166. sizeof(nh)
  167. )) {
  168. return NULL;
  169. }
  170. DllSize = nh.OptionalHeader.SizeOfImage;
  171. } else {
  172. DllSize = 0;
  173. }
  174. }
  175. DllInfo = FindAvailDll();
  176. if (!DllInfo) {
  177. return NULL;
  178. }
  179. DllInfo->Size = DllSize;
  180. strncat( DllInfo->Name, DllName, MAX_NAME_SZ-1 );
  181. DllInfo->BaseAddress = DllAddr;
  182. DllInfo->InList = FALSE;
  183. DllInfo->Enabled = TRUE;
  184. return DllInfo;
  185. }
  186. ULONG
  187. AddApisForDll(
  188. HANDLE hProcess,
  189. PDLL_INFO DllInfo
  190. )
  191. {
  192. IMAGE_DOS_HEADER dh;
  193. IMAGE_NT_HEADERS nh;
  194. IMAGE_EXPORT_DIRECTORY expdir;
  195. PULONG names = NULL;
  196. PULONG addrs = NULL;
  197. PUSHORT ordinals = NULL;
  198. PUSHORT ordidx = NULL;
  199. PAPI_INFO ApiInfo = NULL;
  200. ULONG cnt = 0;
  201. ULONG idx = 0;
  202. ULONG i;
  203. ULONG j;
  204. LPSTR p;
  205. if (*ApiCount == MAX_APIS) {
  206. goto exit;
  207. }
  208. if (!ReadMemory(
  209. hProcess,
  210. (PVOID)DllInfo->BaseAddress,
  211. &dh,
  212. sizeof(dh)
  213. )) {
  214. goto exit;
  215. }
  216. if (dh.e_magic != IMAGE_DOS_SIGNATURE) {
  217. goto exit;
  218. }
  219. if (!ReadMemory(
  220. hProcess,
  221. (PVOID)(DllInfo->BaseAddress + dh.e_lfanew),
  222. &nh,
  223. sizeof(nh)
  224. )) {
  225. goto exit;
  226. }
  227. if (!nh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {
  228. goto exit;
  229. }
  230. if (!ReadMemory(
  231. hProcess,
  232. (PVOID)(DllInfo->BaseAddress +
  233. nh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress),
  234. &expdir,
  235. sizeof(expdir)
  236. )) {
  237. goto exit;
  238. }
  239. names = (PULONG) LocalAlloc( LPTR, expdir.NumberOfNames * sizeof(ULONG) );
  240. addrs = (PULONG) LocalAlloc( LPTR, expdir.NumberOfFunctions * sizeof(ULONG) );
  241. ordinals = (PUSHORT) LocalAlloc( LPTR, expdir.NumberOfNames * sizeof(USHORT) );
  242. ordidx = (PUSHORT) LocalAlloc( LPTR, expdir.NumberOfFunctions * sizeof(USHORT) );
  243. if ((!names) || (!addrs) || (!ordinals) || (!ordidx)) {
  244. goto exit;
  245. }
  246. if (!ReadMemory(
  247. hProcess,
  248. (PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfNames),
  249. names,
  250. expdir.NumberOfNames * sizeof(ULONG)
  251. )) {
  252. goto exit;
  253. }
  254. if (!ReadMemory(
  255. hProcess,
  256. (PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfFunctions),
  257. addrs,
  258. expdir.NumberOfFunctions * sizeof(ULONG)
  259. )) {
  260. goto exit;
  261. }
  262. if (!ReadMemory(
  263. hProcess,
  264. (PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfNameOrdinals),
  265. ordinals,
  266. expdir.NumberOfNames * sizeof(USHORT)
  267. )) {
  268. goto exit;
  269. }
  270. DllInfo->ApiCount = expdir.NumberOfFunctions;
  271. DllInfo->ApiOffset = *ApiOffset;
  272. *ApiOffset += (DllInfo->ApiCount * sizeof(API_INFO));
  273. ApiInfo = (PAPI_INFO)(DllInfo->ApiOffset + (ULONG)DllList);
  274. if (*ApiCount < MAX_APIS) {
  275. for (i=0; i<expdir.NumberOfNames; i++) {
  276. idx = ordinals[i];
  277. ordidx[idx] = TRUE;
  278. ApiInfo[i].Count = 0;
  279. ApiInfo[i].ThunkAddress = 0;
  280. ApiInfo[i].Address = addrs[idx] + DllInfo->BaseAddress;
  281. j = 0;
  282. p = (LPSTR)((LPSTR)MemPtr+*ApiStrings);
  283. do {
  284. ReadMemory(
  285. hProcess,
  286. (PVOID)(DllInfo->BaseAddress + names[i] + j),
  287. &p[j],
  288. 1
  289. );
  290. j += 1;
  291. } while(p[j-1]);
  292. ApiInfo[i].Name = *ApiStrings;
  293. *ApiStrings += (strlen((LPSTR)((LPSTR)MemPtr+*ApiStrings)) + 1);
  294. *ApiCount += 1;
  295. if (*ApiCount == MAX_APIS) {
  296. break;
  297. }
  298. }
  299. }
  300. if (*ApiCount < MAX_APIS) {
  301. for (i=0,idx=expdir.NumberOfNames; i<expdir.NumberOfFunctions; i++) {
  302. if (!ordidx[i]) {
  303. ApiInfo[idx].Count = 0;
  304. ApiInfo[idx].ThunkAddress = 0;
  305. ApiInfo[idx].Address = addrs[i] + DllInfo->BaseAddress;
  306. sprintf(
  307. (LPSTR)((LPSTR)MemPtr+*ApiStrings),
  308. "Ordinal%d",
  309. i
  310. );
  311. ApiInfo[idx].Name = *ApiStrings;
  312. *ApiStrings += (strlen((LPSTR)((LPSTR)MemPtr+*ApiStrings)) + 1);
  313. *ApiCount += 1;
  314. if (*ApiCount == MAX_APIS) {
  315. break;
  316. }
  317. idx += 1;
  318. }
  319. }
  320. }
  321. cnt = DllInfo->ApiCount;
  322. exit:
  323. LocalFree( names );
  324. LocalFree( addrs );
  325. LocalFree( ordinals );
  326. LocalFree( ordidx );
  327. return cnt;
  328. }