Кому нибудь удалось заставить работать на PB10 знаменитую функцию LoadPbDllFromMemory от Семена Матусовского?
- Код: Выделить всё
' ------- Additional API declarations ---------------
%IMAGE_ORDINAL_FLAG = &H80000000
TYPE IMAGE_IMPORT_BY_NAME
Hint AS WORD
ImpName AS ASCIIZ * 254
END TYPE
TYPE IMAGE_IMPORT_DESCRIPTOR
OriginalFirstThunk AS DWORD
TimeDateStamp AS DWORD
ForwarderChain AS DWORD
pName AS DWORD
FirstThunk AS DWORD
END TYPE
TYPE IMAGE_BASE_RELOCATION
VirtualAddress AS DWORD
SizeOfBlock AS DWORD
END TYPE
'===========================================================================
DECLARE FUNCTION EntryPoint(BYVAL hInstance AS DWORD, BYVAL Reason AS DWORD, BYVAL Reserved AS DWORD) AS LONG
FUNCTION GetProcAddressDirectly (BYVAL lpImageDosHeader AS IMAGE_DOS_HEADER PTR, FuncName AS ASCIIZ) AS DWORD
DIM lpImageNtHeaders AS LOCAL IMAGE_NT_HEADERS PTR
DIM lpImageExportDirectory AS LOCAL IMAGE_EXPORT_DIRECTORY PTR
DIM lpNameOrdinals AS LOCAL WORD PTR
DIM lpFunctions AS LOCAL DWORD PTR
DIM lpExpFuncName AS LOCAL ASCIIZ PTR
DIM lpName AS LOCAL DWORD PTR
DIM lpFuncName AS ASCIIZ PTR
DIM i AS LOCAL DWORD
DIM j AS LOCAL DWORD
IF @lpImageDosHeader.e_magic <> %IMAGE_DOS_SIGNATURE THEN FUNCTION = 1: EXIT FUNCTION ' invalid DOS signature
lpImageNtHeaders = lpImageDosHeader + @lpImageDosHeader.e_lfanew
IF @lpImageNtHeaders.Signature <> %IMAGE_NT_SIGNATURE THEN FUNCTION = 1: EXIT FUNCTION ' invalid NT signature
IF @lpImageNtHeaders.FileHeader.SizeOfOptionalHeader <> SIZEOF(@lpImageNtHeaders.OptionalHeader) OR _
@lpImageNtHeaders.OptionalHeader.Magic <> %IMAGE_NT_OPTIONAL_HDR32_MAGIC THEN EXIT FUNCTION
lpImageExportDirectory = @lpImageNtHeaders.OptionalHeader.DataDirectory(%IMAGE_DIRECTORY_ENTRY_EXPORT).VirtualAddress
IF lpImageExportDirectory = 0 THEN EXIT FUNCTION
lpImageExportDirectory = lpImageExportDirectory + lpImageDosHeader
lpNameOrdinals = @lpImageExportDirectory.AddressOfNameOrdinals + lpImageDosHeader
lpName = @lpImageExportDirectory.AddressOfNames + lpImageDosHeader
lpFunctions = @lpImageExportDirectory.AddressOfFunctions + lpImageDosHeader
lpFuncName = VARPTR(FuncName)
IF HIWRD(lpFuncName) THEN ' Name
FOR i = 0 TO @lpImageExportDirectory.NumberOfFunctions - 1
IF @lpFunctions[i] THEN
FOR j = 0 TO @lpImageExportDirectory.NumberOfNames - 1
IF @lpNameOrdinals[j] = i THEN
lpExpFuncName = @lpName[j] + lpImageDosHeader
IF @lpExpFuncName = FuncName THEN FUNCTION = @lpFunctions[i] + lpImageDosHeader: EXIT FUNCTION
END IF
NEXT
END IF
NEXT
ELSE
FOR i = 0 TO @lpImageExportDirectory.NumberOfFunctions - 1
IF lpFuncName = @lpImageExportDirectory.nBase + i THEN
IF @lpFunctions[i] THEN FUNCTION = @lpFunctions[i] + lpImageDosHeader
EXIT FUNCTION
END IF
NEXT
END IF
END FUNCTION
FUNCTION LoadPbDllFromMemory (BYVAL lpRawDll AS DWORD, BYVAL RawDllSize AS DWORD, lpImageDll AS DWORD) AS DWORD
DIM sSysInfo AS LOCAL SYSTEM_INFO
DIM ImagePages AS LOCAL DWORD
DIM lpImageDosHeader AS LOCAL IMAGE_DOS_HEADER PTR
DIM lpImageNtHeaders AS LOCAL IMAGE_NT_HEADERS PTR
DIM lpImageSectionHeader AS LOCAL IMAGE_SECTION_HEADER PTR
DIM lpImageImportDescriptor AS LOCAL IMAGE_IMPORT_DESCRIPTOR PTR
DIM lpImageImportByName AS LOCAL IMAGE_IMPORT_BY_NAME PTR
DIM lpImageBaseRelocTable AS LOCAL IMAGE_BASE_RELOCATION PTR
DIM lpDllName AS LOCAL ASCIIZ PTR
DIM szDllName AS LOCAL STRING
DIM hDll AS LOCAL DWORD
DIM lpFuncNameRef AS LOCAL DWORD PTR
DIM lpFuncAddr AS LOCAL DWORD PTR
DIM lpTypeOffset AS WORD PTR
DIM TpOffset AS WORD
DIM lpLink AS LOCAL DWORD PTR
DIM fOldProtect AS LOCAL DWORD
DIM i AS LOCAL DWORD
DIM j AS LOCAL DWORD
DIM k AS LOCAL DWORD
DIM Protection() AS LOCAL BYTE
DIM Addr1 AS LOCAL DWORD
DIM Addr2 AS LOCAL DWORD
DIM Pg AS LOCAL DWORD
DIM Pg1 AS LOCAL DWORD
DIM Pg2 AS LOCAL DWORD
lpImageDosHeader = lpRawDll
IF RawDllSize < SIZEOF(IMAGE_DOS_HEADER) THEN FUNCTION = 1: EXIT FUNCTION
IF @lpImageDosHeader.e_magic <> %IMAGE_DOS_SIGNATURE THEN FUNCTION = 1: EXIT FUNCTION ' invalid DOS signature
IF RawDllSize < @lpImageDosHeader.e_lfanew + SIZEOF(IMAGE_NT_HEADERS) THEN FUNCTION = 1: EXIT FUNCTION
lpImageNtHeaders = lpImageDosHeader + @lpImageDosHeader.e_lfanew
IF @lpImageNtHeaders.Signature <> %IMAGE_NT_SIGNATURE THEN FUNCTION = 1: EXIT FUNCTION ' invalid NT signature
IF @lpImageNtHeaders.FileHeader.SizeOfOptionalHeader <> SIZEOF(@lpImageNtHeaders.OptionalHeader) OR _
@lpImageNtHeaders.OptionalHeader.Magic <> %IMAGE_NT_OPTIONAL_HDR32_MAGIC THEN FUNCTION = 1: EXIT FUNCTION
IF @lpImageNtHeaders.FileHeader.NumberOfSections < 1 THEN FUNCTION = 1: EXIT FUNCTION
FOR i = 0 TO %IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1
IF @lpImageNtHeaders.OptionalHeader.DataDirectory(i).VirtualAddress <> 0 THEN
SELECT CASE AS LONG i
CASE %IMAGE_DIRECTORY_ENTRY_EXPORT ' Export Directory
CASE %IMAGE_DIRECTORY_ENTRY_IMPORT ' Import Directory
CASE %IMAGE_DIRECTORY_ENTRY_RESOURCE ' Resource Directory
CASE %IMAGE_DIRECTORY_ENTRY_BASERELOC ' Base Relocation Table
CASE %IMAGE_DIRECTORY_ENTRY_IAT ' Import Address Table
CASE ELSE ' Strange for PB
FUNCTION = 2: EXIT FUNCTION
END SELECT
END IF
NEXT
lpImageSectionHeader = lpImageNtHeaders + SIZEOF(IMAGE_NT_HEADERS)
k = lpImageSectionHeader - lpImageDosHeader + SIZEOF(IMAGE_SECTION_HEADER) * @lpImageNtHeaders.FileHeader.NumberOfSections
j = k
FOR i = 0 TO @lpImageNtHeaders.FileHeader.NumberOfSections - 1
j = MAX(j, @lpImageSectionHeader[i].VirtualAddress + @lpImageSectionHeader[i].SizeOfRawData)
NEXT
GetSystemInfo sSysInfo
ImagePages = j \ sSysInfo.dwPageSize: IF (j MOD sSysInfo.dwPageSize) THEN INCR ImagePages
lpImageDll = VirtualAlloc(BYVAL 0, CDWD(ImagePages * sSysInfo.dwPageSize), %MEM_COMMIT, %PAGE_EXECUTE_READWRITE)
IF lpImageDll = 0 THEN FUNCTION = 5: EXIT FUNCTION
MoveMemory BYVAL lpImageDll, BYVAL lpRawDll, k
FOR i = 0 TO @lpImageNtHeaders.FileHeader.NumberOfSections - 1
MoveMemory BYVAL CDWD(lpImageDll + @lpImageSectionHeader[i].VirtualAddress), _
BYVAL CDWD(lpRawDll + @lpImageSectionHeader[i].PointerToRawData), @lpImageSectionHeader[i].SizeOfRawData
NEXT
' Switch to new image
lpImageDosHeader = lpImageDll
lpImageNtHeaders = lpImageDosHeader + @lpImageDosHeader.e_lfanew
lpImageSectionHeader = lpImageNtHeaders + SIZEOF(IMAGE_NT_HEADERS)
' Import section
lpImageImportDescriptor = @lpImageNtHeaders.OptionalHeader.DataDirectory(%IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress
IF lpImageImportDescriptor <> 0 THEN
lpImageImportDescriptor = lpImageImportDescriptor + lpImageDosHeader
WHILE @lpImageImportDescriptor.OriginalFirstThunk <> 0 OR @lpImageImportDescriptor.FirstThunk <> 0 ' Dlls
lpDllName = @lpImageImportDescriptor.pName + lpImageDosHeader
szDllName = @lpDllName
hDll = GetModuleHandle(BYVAL STRPTR(szDllName))
IF hDll = 0 THEN hDll = LoadLibrary(BYVAL STRPTR(szDllName))
IF hDll = 0 THEN FUNCTION = 2: EXIT FUNCTION ' Can't find
lpFuncNameRef = @lpImageImportDescriptor.OriginalFirstThunk + lpImageDosHeader
lpFuncAddr = @lpImageImportDescriptor.FirstThunk + lpImageDosHeader
IF lpFuncNameRef = lpImageDosheader THEN lpFuncNameRef = lpFuncAddr
WHILE @lpFuncNameRef <> 0
lpImageImportByName = @lpFuncNameRef + lpImageDosHeader
IF (@lpFuncNameRef AND %IMAGE_ORDINAL_FLAG) THEN _
@lpFuncAddr = GetProcAddress(hDll, BYVAL @lpFuncNameRef AND &HFFFF???) ELSE _
@lpFuncAddr = GetProcAddress(hDll, @lpImageImportByName.ImpName)
IF @lpFuncAddr = 0 THEN FUNCTION = 2: EXIT FUNCTION
INCR lpFuncAddr
INCR lpFuncNameRef
WEND
INCR lpImageImportDescriptor
LOOP
END IF
lpImageBaseRelocTable = @lpImageNtHeaders.OptionalHeader.DataDirectory(%IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress
IF lpImageBaseRelocTable <> 0 THEN
lpImageBaseRelocTable = lpImageBaseRelocTable + lpImageDosHeader
WHILE @lpImageBaseRelocTable.VirtualAddress <> 0
lpTypeOffset = lpImageBaseRelocTable + SIZEOF(IMAGE_BASE_RELOCATION)
WHILE lpTypeOffset < lpImageBaseRelocTable + @lpImageBaseRelocTable.SizeOfBlock
TpOffset = @lpTypeOffset AND &HF000??
IF TpOffset = &H3000 THEN
lpLink = lpImageDosHeader + @lpImageBaseRelocTable.VirtualAddress + (@lpTypeOffset AND &HFFF??)
@lpLink = @lpLink - @lpImageNtHeaders.OptionalHeader.ImageBase + lpImageDosHeader
ELSEIF TpOffSet = 0 THEN
ELSE
FUNCTION = 3: EXIT FUNCTION ' Uknown type
END IF
INCR lpTypeOffset
WEND
lpImageBaseRelocTable = lpImageBaseRelocTable + @lpImageBaseRelocTable.SizeOfBlock
WEND
END IF
REDIM Protection(ImagePages - 1)
FOR i = 0 TO @lpImageNtHeaders.FileHeader.NumberOfSections
IF i = @lpImageNtHeaders.FileHeader.NumberOfSections THEN
Addr1 = 0: Addr2 = k: j = &H60000000??? ' %PAGE_EXECUTE_READ
ELSE
Addr1 = @lpImageSectionHeader[i].VirtualAddress
Addr2 = @lpImageSectionHeader[i].SizeOfRawData
j = @lpImageSectionHeader[i].Characteristics
END IF
Addr2 = Addr1 + Addr2 - 1
Pg1 = Addr1 \ sSysInfo.dwPageSize
Pg2 = Addr2 \ sSysInfo.dwPageSize
FOR Pg = Pg1 TO Pg2
IF (j AND &H20000000???) THEN Protection(Pg) = Protection(Pg) OR 1 ' Execute
IF (j AND &H40000000???) THEN Protection(Pg) = Protection(Pg) OR 2 ' Read
IF (j AND &H80000000???) THEN Protection(Pg) = Protection(Pg) OR 4 ' Write
NEXT
NEXT
Addr1 = lpImageDosHeader
FOR Pg = 0 TO ImagePages - 1
SELECT CASE AS LONG Protection(Pg)
CASE 2: fOldProtect = %PAGE_READONLY
CASE 3: fOldProtect = %PAGE_EXECUTE_READ
CASE 6: fOldProtect = %PAGE_READWRITE
CASE ELSE: fOldProtect = %PAGE_EXECUTE_READWRITE ' Ignore strange combinations
END SELECT
IF fOldProtect <> %PAGE_EXECUTE_READWRITE THEN _
IF VirtualProtect (BYVAL Addr1, sSysInfo.dwPageSize, fOldProtect, fOldProtect) = 0 THEN FUNCTION = 4: EXIT FUNCTION
Addr1 = Addr1 + sSysInfo.dwPageSize
NEXT
i = @lpImageNtHeaders.OptionalHeader.AddressOfEntryPoint + lpImageDosHeader
CALL DWORD i USING EntryPoint (lpImageDosHeader, %DLL_PROCESS_ATTACH, 0)
END FUNCTION
FUNCTION UnloadPbDllFromMemory (BYVAL lpImageDosHeader AS IMAGE_DOS_HEADER PTR) AS DWORD
DIM lpImageNtHeaders AS LOCAL IMAGE_NT_HEADERS PTR
DIM i AS LOCAL DWORD
lpImageNtHeaders = lpImageDosHeader + @lpImageDosHeader.e_lfanew
i = @lpImageNtHeaders.OptionalHeader.AddressOfEntryPoint + lpImageDosHeader
CALL DWORD i USING EntryPoint (lpImageDosHeader, %DLL_PROCESS_DETACH, 0)
FUNCTION = VirtualFree (BYVAL lpImageDosHeader, 0, %MEM_RELEASE)
END FUNCTION