Advertisement
Guest User

[Cramel] MemDLL

a guest
Aug 5th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.73 KB | None | 0 0
  1. Importar "Cramel.cml"
  2.  
  3. Estruct LIB_INFO,_
  4. Base,_ ' Dirección base de la librería en memoria.
  5. NumLibs,_ ' Número de librerías que esta importa.
  6. Librerías[]:Entero,_ ' Identificadores de las librerias importadas.
  7. @NT:IMAGE_NT_HEADERS,_ ' Cabecera PE.
  8. Inicializado:Booleano ' Establece si fue inicializado.
  9.  
  10. Prototipo LibEntryPoint(Instancia,Razón:Entero,Opcional Reservado:Entero):Entero
  11.  
  12. Proc FIELD_OFFSET(Estructura,Miembro:Entero):Entero
  13. Resultado = (Miembro - Estructura)
  14. FinProc
  15.  
  16. Proc IMAGE_FIRST_SECTION(Referencia NT:IMAGE_NT_HEADERS):Entero
  17. Resultado = NT@ + (FIELD_OFFSET(NT@,NT.OptionalHeader@) + NT.FileHeader.SizeOfOptionalHeader)
  18. FinProc
  19.  
  20. Proc GET_HEADER_DICTIONARY(Mem:Entero,Indice:Byte):Entero
  21. Var @NT:IMAGE_NT_HEADERS
  22. NT@ = GET_NT_HEADERS(Mem)
  23. Resultado = NT.OptionalHeader.DataDirectory[Indice]@
  24. FinProc
  25.  
  26. Proc GET_DOS_HEADER(Mem:Entero):Entero
  27. Resultado = Mem
  28. FinProc
  29.  
  30. Proc GET_NT_HEADERS(Mem:Entero):Entero
  31. Var @DOS_HEADER:IMAGE_DOS_HEADER
  32. DOS_HEADER@ = GET_DOS_HEADER(Mem)
  33. Resultado = Mem + DOS_HEADER.e_lfanew
  34. FinProc
  35.  
  36. Proc IMAGE_ORDINAL(Ordinal:Entero):Word
  37. Resultado = (Ordinal And &FFFF)
  38. FinProc
  39.  
  40. Proc IMAGE_SNAP_BY_ORDINAL(Ordinal:Entero):Booleano
  41. Resultado = (Ordinal And IMAGE_ORDINAL_FLAG32)
  42. FinProc
  43.  
  44. Proc GET_SECTION_PROTECTION(Characteristics:Entero):Entero
  45. Var Flag:Byte
  46. Si Characteristics And IMAGE_SCN_MEM_EXECUTE Entonces
  47. Flag = Flag + 1 ' Flag = 0 o 1
  48. FinSi
  49. Si Characteristics And IMAGE_SCN_MEM_READ Entonces
  50. Flag = Flag + 2 ' Flag = 1 o 2 o 3
  51. FinSi
  52. Si Characteristics And IMAGE_SCN_MEM_WRITE Entonces
  53. Flag = Flag + 3 ' Flag = 3 o 4 o 5 o 6
  54. FinSi
  55. Seleccionar Flag
  56. Caso 0 ' Nada :0
  57. Caso 1 ' Ejecutable
  58. Resultado = PAGE_EXECUTE
  59. Caso 2 ' Solo lectura
  60. Resultado = PAGE_READONLY
  61. Caso 3 ' Lectura y ejecutable
  62. Resultado = PAGE_EXECUTE_READ
  63. Caso 4 ' Ejecutable y editable
  64. Resultado = PAGE_EXECUTE_WRITECOPY
  65. Caso 5 ' Lectura y editable
  66. Resultado = PAGE_READWRITE
  67. Caso 6 ' Ejecutable, lectura y editable.
  68. Resultado = PAGE_EXECUTE_READWRITE
  69. FinSeleccionar
  70. FinProc
  71.  
  72. ' Copia las secciones del archivo en memoria.
  73. Proc CopiarSecciones(Referencia Res:LIB_INFO,Referencia NT:IMAGE_NT_HEADERS,LibPtr:Entero)
  74. Var i:Entero
  75. Var @SECHeader:IMAGE_SECTION_HEADER
  76. Var Tamaño:Entero
  77. Var Des:Entero
  78. SECHeader@ = IMAGE_FIRST_SECTION(Res.NT)
  79. Contar i a (Res.NT.FileHeader.NumberOfSections - 1)
  80. Si SECHeader.SizeOfRawData = 0 Entonces
  81. Tamaño = NT.OptionalHeader.SectionAlignment
  82. Si Tamaño Entonces
  83. Des = VirtualAlloc(Res.Base + SECHeader.VirtualAddress,Tamaño,MEM_COMMIT,PAGE_READWRITE)
  84. SECHeader.Misc.PhysicalAddress = Des
  85. memset(Des,0,Tamaño)
  86. FinSi
  87. SiNo
  88. Des = VirtualAlloc(Res.Base + SECHeader.VirtualAddress,SECHeader.SizeOfRawData,MEM_COMMIT,PAGE_READWRITE)
  89. memcpy(Des,LibPtr + SECHeader.PointerToRawData,SECHeader.SizeOfRawData)
  90. SECHeader.Misc.PhysicalAddress = Des
  91. FinSi
  92. SECHeader@ = SECHeader@@ + &IMAGE_SECTION_HEADER
  93. Seguir
  94. FinProc
  95.  
  96. ' Importamos las librerias requeridas por el archivo en memoria y registramos los procedimientos.
  97. Proc RegImportaciones(Referencia Res:LIB_INFO):Booleano
  98. Var @Directorio:IMAGE_DATA_DIRECTORY
  99. Var @ImportDesc:IMAGE_IMPORT_DESCRIPTOR
  100. Var ResLoad:Entero
  101. Var @OrFirstThunk:Entero
  102. Var @ProcRef:Entero
  103. Var @ImgImport:IMAGE_IMPORT_BY_NAME
  104. Directorio@ = GET_HEADER_DICTIONARY(Res.Base,IMAGE_DIRECTORY_ENTRY_IMPORT)
  105. Si Directorio.Size Entonces
  106. ImportDesc@ = Res.Base + Directorio.VirtualAddress
  107. Mientras ImportDesc.Name
  108. ResLoad = LoadLibrary(CadDePtr(Res.Base + ImportDesc.Name))
  109. Si ImportDesc.OriginalFirstThunk Entonces
  110. OrFirstThunk@ = Res.Base + ImportDesc.OriginalFirstThunk
  111. SiNo
  112. OrFirstThunk@ = Res.Base + ImportDesc.FirstThunk
  113. FinSi
  114. ProcRef@ = Res.Base + ImportDesc.FirstThunk
  115. Mientras OrFirstThunk
  116. Si IMAGE_SNAP_BY_ORDINAL(OrFirstThunk) Entonces
  117. ProcRef = GetProcAddress(ResLoad,EntCad(IMAGE_ORDINAL(OrFirstThunk)))
  118. SiNo
  119. ImgImport@ = Res.Base + OrFirstThunk
  120. ProcRef = GetProcAddress(ResLoad,CadDePtr(ImgImport.Name[0]@))
  121. FinSi
  122. Si ProcRef = 0 Entonces Salir Mientras
  123. OrFirstThunk@ = OrFirstThunk@@ + &Entero
  124. ProcRef@ = ProcRef@@ + &Entero
  125. FinMientras
  126. ImportDesc@ = ImportDesc@@ + &IMAGE_IMPORT_DESCRIPTOR
  127. ' Almacenamos el identificador de la libreria cargada para ser liberada mas tarde.
  128. ReDim Preservar Res.Librerías,Res.NumLibs + 1
  129. Res.Librerías[Res.NumLibs] = ResLoad
  130. Res.NumLibs = Res.NumLibs + 1
  131. FinMientras
  132. FinSi
  133. FinProc
  134.  
  135. ' Liberamos las librerias importadas.
  136. Proc LibImportaciones(Referencia Res:LIB_INFO):Booleano
  137. Var i:Entero
  138. Contar i a Res.NumLibs - 1
  139. Si Res.Librerías[i] <> INVALID_HANDLE_VALUE Entonces FreeLibrary(Res.Librerías[i])
  140. Seguir
  141. FinProc
  142.  
  143. ' Limpiamos de memoria las secciones y protegemos las que corresponden.
  144. Proc LimpiarSecciones(Referencia Res:LIB_INFO)
  145. Var @SECHeader:IMAGE_SECTION_HEADER
  146. Var i:Entero
  147. Var Protección:Entero
  148. Var Tamaño:Entero
  149. SECHeader@ = IMAGE_FIRST_SECTION(Res.NT)
  150. Contar i a (Res.NT.FileHeader.NumberOfSections - 1)
  151. Si SECHeader.Characteristics And IMAGE_SCN_MEM_DISCARDABLE Entonces
  152. ' La sección es descartable, liberamos la memoria y retrocedemos a otra sección.
  153. VirtualFree(SECHeader.Misc.PhysicalAddress,SECHeader.SizeOfRawData,MEM_DECOMMIT)
  154. SECHeader@ = SECHeader@@ - &IMAGE_SECTION_HEADER
  155. SiNo
  156. Protección = GET_SECTION_PROTECTION(SECHeader.Characteristics)
  157. Si SECHeader.Characteristics And IMAGE_SCN_MEM_NOT_CACHED Entonces Protección = Protección + PAGE_NOCACHE
  158. Tamaño = SECHeader.SizeOfRawData
  159. Si Tamaño Entonces
  160. Si SECHeader.Characteristics And IMAGE_SCN_CNT_INITIALIZED_DATA Entonces
  161. Tamaño = Res.NT.OptionalHeader.SizeOfInitializedData
  162. OSi SECHeader.Characteristics And IMAGE_SCN_CNT_UNINITIALIZED_DATA Entonces
  163. Tamaño = Res.NT.OptionalHeader.SizeOfUnitializedData
  164. FinSi
  165. Si Tamaño Entonces VirtualProtect(SECHeader.Misc.PhysicalAddress,SECHeader.SizeOfRawData,Protección)
  166. FinSi
  167. FinSi
  168. SECHeader@ = SECHeader@@ + &IMAGE_SECTION_HEADER
  169. Seguir
  170. FinProc
  171.  
  172. ' Ajustamos las referencias de memoria.
  173. Proc RelocaciónBase(Referencia Res:LIB_INFO)
  174. Var @Directorio:IMAGE_DATA_DIRECTORY
  175. Var @Reloc:IMAGE_BASE_RELOCATION
  176. Var @Des:Entero
  177. Var @RelocInfo:Word
  178. Var @Pos:Word
  179. Var i:Entero
  180. Var Tipo:Word
  181. Directorio@ = GET_HEADER_DICTIONARY(Res.Base,IMAGE_DIRECTORY_ENTRY_BASERELOC)
  182. Si Directorio.Size Entonces
  183. Reloc@ = Res.Base + Directorio.VirtualAddress
  184. Mientras Reloc.VirtualAddress
  185. RelocInfo@ = Reloc@@ + IMAGE_SIZEOF_BASE_RELOCATION
  186. i = 0
  187. ' DIOS! COMO ME COSTO HACER ANDAR ESTE CÓDIGO!!
  188. ' PUT* Delphi, Put* C.
  189. Contar i a ((Reloc.SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2) - 1
  190. Des@ = Res.Base + Reloc.VirtualAddress
  191. Si (RelocInfo Shr &C) = IMAGE_REL_BASED_HIGHLOW Entonces
  192. Des@ = Des@@ + (RelocInfo And &FFF)
  193. Des = LOWORD(Des) + Res.Base
  194. FinSi
  195. RelocInfo@ = RelocInfo@@ + &Word
  196. Seguir
  197. Reloc@ = Reloc@@ + Reloc.SizeOfBlock
  198. FinMientras
  199. FinSi
  200. FinProc
  201.  
  202. ' Invocamos el punto de entrada.
  203. Proc InvocarPuntoDeEntrada(Referencia Res:LIB_INFO,Bandera:Entero):Booleano
  204. Var @EntryPoint:LibEntryPoint
  205. Si Res.NT.OptionalHeader.AddressOfEntryPoint Entonces
  206. EntryPoint@ = Res.Base + Res.NT.OptionalHeader.AddressOfEntryPoint
  207. Resultado = EntryPoint(Res.Base,Bandera,0)
  208. Res.Inicializado = Resultado
  209. FinSi
  210. FinProc
  211.  
  212. Proc MemLoadLibrary(LibPtr:Entero):LIB_INFO
  213.  
  214. Var @PEHeader:IMAGE_NT_HEADERS
  215. Var @DOSHeader:IMAGE_DOS_HEADER
  216. Var Headers:Entero
  217. Var Reubicar:Booleano
  218. Var LibBase:Entero
  219.  
  220. DOSHeader@ = GET_DOS_HEADER(LibPtr)
  221. PEHeader@ = GET_NT_HEADERS(LibPtr)
  222.  
  223. Var Base:Entero
  224.  
  225. Base = VirtualAlloc(PEHeader.OptionalHeader.ImageBase,PEHeader.OptionalHeader.SizeOfImage,MEM_RESERVE + MEM_COMMIT,PAGE_READWRITE)
  226.  
  227. Si Base = 0 Entonces
  228. Base = VirtualAlloc(0,PEHeader.OptionalHeader.SizeOfImage,MEM_RESERVE + MEM_COMMIT,PAGE_READWRITE)
  229. Si Base = 0 Entonces Salir
  230. Reubicar = Verdadero
  231. LibBase = PEHeader.OptionalHeader.ImageBase
  232. FinSi
  233.  
  234. ' Comprometemos la memoria para las cabeceras, esto se hacce re-invocando VirtualAlloc.
  235.  
  236. Headers = VirtualAlloc(Base,PEHeader.OptionalHeader.SizeOfHeaders,MEM_COMMIT,PAGE_READWRITE)
  237.  
  238. memcpy(Headers,LibPtr,DOSHeader.e_lfanew + PEHeader.OptionalHeader.SizeOfHeaders)
  239.  
  240. Resultado.Base = Base
  241. Resultado.NT@ = PEHeader@@
  242. Resultado.NT.OptionalHeader.ImageBase = Base
  243.  
  244. CopiarSecciones(Resultado,PEHeader,LibPtr)
  245.  
  246. Si Reubicar Entonces RelocaciónBase(Resultado)
  247.  
  248. RegImportaciones(Resultado)
  249.  
  250. LimpiarSecciones(Resultado)
  251.  
  252. InvocarPuntoDeEntrada(Resultado,DLL_PROCESS_ATTACH)
  253.  
  254. 'VirtualFree(Base,0,MEM_RELEASE)
  255.  
  256. FinProc
  257.  
  258. Proc MemGetProcAddress(Referencia Modulo:LIB_INFO,Nombre:Cadena,Opcional Sensitivo:Booleano):Entero
  259. Var @Directorio:IMAGE_DATA_DIRECTORY
  260. Var @Export:IMAGE_EXPORT_DIRECTORY
  261. Var @NomRef:Entero
  262. Var @Ord:Word
  263. Var i:Entero
  264. Var iOrd:Entero
  265. Var @PtrProc:Entero
  266. iOrd = -1
  267. Directorio@ = GET_HEADER_DICTIONARY(Modulo.Base,IMAGE_DIRECTORY_ENTRY_EXPORT)
  268. Si Directorio.Size Entonces
  269. Export@ = Modulo.Base + Directorio.VirtualAddress
  270. Si (Export.NumberOfNames = 0) o (Export.NumberOfFunctions = 0) Entonces Salir
  271. NomRef@ = Modulo.Base + Export.AddressOfNames
  272. Ord@ = Modulo.Base + Export.AddressOfNameOrdinals
  273. Contar i a Export.NumberOfNames - 1
  274. Si Sensitivo Entonces
  275. Si strcmp(CadDePtr(Modulo.Base + NomRef),Nombre) = 0 Entonces
  276. iOrd = Ord
  277. Salir Contar
  278. FinSi
  279. SiNo
  280. Si strcmpi(CadDePtr(Modulo.Base + NomRef),Nombre) = 0 Entonces
  281. iOrd = Ord
  282. Salir Contar
  283. FinSi
  284. FinSi
  285. NomRef = NomRef + &Entero
  286. Ord = Ord + &Word
  287. Seguir
  288. Si iOrd = -1 Entonces Salir
  289. Si iOrd > Export.NumberOfFunctions - 1 Entonces Salir
  290. PtrProc@ = (Modulo.Base + (Export.AddressOfFunctions + (iOrd * 4)))
  291. Resultado = Modulo.Base + PtrProc
  292. FinSi
  293. FinProc
  294.  
  295. Proc MemFreeLibrary(Referencia Res:LIB_INFO)
  296. Var i:Entero
  297. Si Res.Inicializado Entonces
  298. InvocarPuntoDeEntrada(Res,DLL_PROCESS_DETACH)
  299. Res.Inicializado = Falso
  300. LibImportaciones(Res)
  301. Si Res.Base Entonces
  302. VirtualFree(Res.Base,0,MEM_RELEASE)
  303. Si Res.NT@@ Entonces Res.NT@ = 0
  304. Res.Base = 0
  305. ReDim Res.Librerías,0
  306. Res.NumLibs = 0
  307. FinSi
  308. FinSi
  309. FinProc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement