DLL Export Viewer
Re: DLL Export Viewer
Yep, looks good. If you could squeeze in the module count (maybe in the header, in left hand list?) it would be perfect.
Part of my AHK work can be found here.
Re: DLL Export Viewer
If I would minify the GetDllExports function to return the number of functions in a module it would looks like this. And every dll needs a call to this function for the listview.
If you find something else on your search engine here let me now =)
or do you mean the count of moduls in this listview?
Code: Select all
MsgBox % GetNumberOfFunctions("gdi32.dll") ; -> 923 on Win10
GetNumberOfFunctions(DllFile)
{
VarSetCapacity(LOADED_IMAGE, 88, 0)
if (DllCall("imagehlp\MapAndLoad", "astr", DllFile, "ptr", 0, "ptr", &LOADED_IMAGE, "int", 1, "int", 1)) {
Machine := NumGet(NumGet(LOADED_IMAGE, A_PtrSize * 3, "uptr") + 4, "ushort")
if (Machine = 0x014c) || (Machine = 0x8664)
if (IMAGE_EXPORT_DIRECTORY := DllCall("imagehlp\ImageDirectoryEntryToData", "ptr", NumGet(LOADED_IMAGE, A_PtrSize * 2, "uptr"), "int", 0, "ushort", 0, "uint*", size, "uptr"))
NumberOfNames := NumGet(IMAGE_EXPORT_DIRECTORY + 0x18, "uint")
DllCall("imagehlp\UnMapAndLoad", "ptr", &LOADED_IMAGE)
}
return NumberOfNames
}
or do you mean the count of moduls in this listview?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
I meant the count of libraries/files (modules as you call them) in the selected directory.
I.e. user selects C:\Windows\System32 and the left-hand list displays XXXX Modules (or libraries or whatever) in its header.
May not be that important to most people but some control freaks (like me ) might get tipped off it the current count doesn't match the previous one.
I'll have to look again in my Pale Moon profile or just run it (ugh, the bloat I created there!) and then fire up all search engines, one at a time, and look at the queries. Tedious job, I tell you that.
I.e. user selects C:\Windows\System32 and the left-hand list displays XXXX Modules (or libraries or whatever) in its header.
May not be that important to most people but some control freaks (like me ) might get tipped off it the current count doesn't match the previous one.
I'll have to look again in my Pale Moon profile or just run it (ugh, the bloat I created there!) and then fire up all search engines, one at a time, and look at the queries. Tedious job, I tell you that.
Part of my AHK work can be found here.
Re: DLL Export Viewer
Yes, that's the idea.
Yikes, over 3000 libraries?! Gosh…
Yikes, over 3000 libraries?! Gosh…
Part of my AHK work can be found here.
Re: DLL Export Viewer
Looks great!
Most wanted
Cheers.
Most wanted
- Bookmark dll
- Put GetProcAddress code to clipboard. Eg, clipboard = DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\LoadLibrary", "Str", ModuleName, "Ptr"), "AStr", Function Name, "Ptr")
Cheers.
Re: DLL Export Viewer
Getting procedure address for named functions may be of use sometimes, probably mostly when trying to improve script speed, but more useful would be for ordinals, where there's no function name to call directly.
Unfortunately I haven't seen any ordinals with this script… yet.
Unfortunately I haven't seen any ordinals with this script… yet.
Part of my AHK work can be found here.
Re: DLL Export Viewer
Where DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", ModuleName, "Ptr"), "AStr", FunctionName, "Ptr") is for already loaded library's like kernel32 / user32 / gdi32 /...
You should use LoadLibrary in place of GetModuleHandle if the dll is not already loaded.
But:
@lexikos
Correct me if I missed something
You should use LoadLibrary in place of GetModuleHandle if the dll is not already loaded.
But:
We got this already discussed in an old thread of mine (https://autohotkey.com/boards/viewtopic ... 461#p46461)lexikos wrote:It's also completely ineffective to do the GetProcAddress "optimization" for functions in DLLs which AutoHotkey imports (i.e. because they are always resolved at startup). At minimum, that includes User32.dll, Kernel32.dll, ComCtl32.dll, and Gdi32.dll. That is, unless the function name is an expression/variable.
@lexikos
Correct me if I missed something
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
It is not for explicit dllcalls, it is for passing fnptrs to compiled code.
Edit: I guess there isn't a general interest
Edit: I guess there isn't a general interest
Re: DLL Export Viewer
So you want on the rightlick menu (or gui menu) a copy address of an exported function?
How should I name this? Copy ProcAddress or Copy FuncAddress or something else?
btw. can someone check the whole english part of the gui? it's not my main language
How should I name this? Copy ProcAddress or Copy FuncAddress or something else?
btw. can someone check the whole english part of the gui? it's not my main language
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
Where it is matters less, what I need in the clipboard is the explicit text,
where ModuleName and FunctionName matches whatever is selected.
Code: Select all
DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", ModuleName, "Ptr"), "AStr", FunctionName, "Ptr")
Re: DLL Export Viewer
File -> Load Common Dll's change to -> File -> Load common Dlls. ' is for possessive, not plural.btw. can someone check the whole english part of the gui? it's not my main language
I see nothing else.
Edit: ModuleName -> Module Name in the right ListView.
Re: DLL Export Viewer
Changed =)
What do you mean with Bookmark?
Most used modules? If yes, that's why I added common dll's in menu.
If I move Module Name (List) to right the Expand Listview menu will be removed (no need any more)
What do you mean with Bookmark?
Most used modules? If yes, that's why I added common dll's in menu.
If I move Module Name (List) to right the Expand Listview menu will be removed (no need any more)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
With Bookmark, I mean something like save to ini file, so next time I load the app, I can select my favourite* modules from some list or something. Some dll names are hard for me to remember
*Yes, I have favourite modules
Edit
*Yes, I have favourite modules
Edit
this one will be bigger and bigger
Last edited by Helgef on 03 Aug 2017, 09:20, edited 1 time in total.
Re: DLL Export Viewer
I love one-file-ahk-projects.. but since this one will be bigger and bigger, I will move to includes now and will the first time (for me) add releases (x86.exe - x64.exe - ahk.zip)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
This is rather a proof of concept than an improvement. I was wondering whether all needed information could be retrieved directly from the DLL file without calling external functions. Apparently ist's possible. The only required step seems to be to 'load' the section data contained in the file to their (relative) virtual addresses as defined in the section headers. After this the RVAs defined in the optional header data directory entry and the export directory table are matching the corresponding data.
It also demonstrates the power of AHK's File Object.
It also demonstrates the power of AHK's File Object.
Code: Select all
#NoEnv
SetBatchLines, -1
DllFile := A_WinDir . "\System32\Ntdll.dll"
S := A_TickCount
Exports := DllExports(DllFile)
T := A_TickCount - S
Module := Exports.Module
Named := Exports.Named
Bitness := Exports.Bitness
OrdBase := Exports.OrdBase
Gui, Add, ListView, xm ym w800 h450 Count%Named% vMyLV1 hWndhMyLV1 +LV0x14000, Ordinal|Function Name|Entry Point (RVA)
For Index, Function In Exports.Functions
LV_Add("", Function.Ordinal, Function.Name, Function.EntryPoint)
LV_ModifyCol(1, "Integer 50")
LV_ModifyCol(2, "AutoHdr")
LV_ModifyCol(3, "AutoHdr")
Gui, Add, StatusBar
SB_SetText(" Module: " . Module . " - " . Bitness . "-bit - " . Named . " named functions - ordinal base: " . OrdBase)
Gui, Show, , %DllFile% (%T% ms)
Return
; --------------------------------------------------------------------------------------------------------------------------------
GuiClose:
ExitApp
; ================================================================================================================================
DllExports(DllPath) {
Static LocSignatureOff := 0x3C ; location of the file offset to the PE signature
Static SizeOfSignature := 4 ; size of the PE signature
Static SizeOfCoffHdr := 20 ; size of the COFF header
Static SizeOfSectionHdr := 40 ; size of a section header
; Check the file path ---------------------------------------------------------------------------------------------------------
SplitPath, DllPath, , , FileExt
If (FileExt <> "dll")
Return !(ErrorLevel := 1) ; invalid file extension
; Open the file ---------------------------------------------------------------------------------------------------------------
If !(DllFile := FileOpen(DllPath, "r"))
Return !(ErrorLevel := 2) ; could not open the file for reading
If (DllFile.Pos <> 0)
Return !(ErrorLevel := 3) ; AHK found a BOM, it isn't a DLL
; MS-DOS header----------------------------------------------------------------------------------------------------------------
DllFile.RawRead(RawBytes, 2)
If !(StrGet(&RawBytes, 2, "CP0") == "MZ")
Return !(ErrorLevel := 4) ; no MS-DOS stub
; PE Signature ----------------------------------------------------------------------------------------------------------------
DllFile.Pos := LocSignatureOff
DllFile.Pos := DllFile.ReadUInt() ; offset to the PE signature
; Read the signature and advance the file pointer to the begin of the COFF header.
DllFile.RawRead(RawBytes, SizeOfSignature)
If !(StrGet(&RawBytes, SizeOfSignature, "CP0") == "PE")
Return !(ErrorLevel := 5) ; no PE file
; COFF header -----------------------------------------------------------------------------------------------------------------
; Machine types: IMAGE_FILE_MACHINE_I386 (x86) = 0x014C, IMAGE_FILE_MACHINE_AMD64 (x64) = 0x8664
; Characteristics: IMAGE_FILE_DLL = 0x2000
; Read the COFF file header and advance the file pointer to the begin of the optional header.
DllFile.RawRead(RawBytes, SizeOfCoffHdr)
Machine := NumGet(RawBytes, 0, "UShort") ; the type of the target machine
If (Machine <> 0x014C) && (Machine <> 0x8664)
Return !(ErrorLevel := 6) ; wrong CPU type
NumberOfSections := NumGet(RawBytes, 2, "UShort") ; the number of section headers
SizeOfOptionalHeader := NumGet(RawBytes, 16, "UShort") ; the size of the optional header (required for DLL files)
Characteristics := NumGet(RawBytes, 18, "UShort") ; the attributes of the file
If !(Characteristics & 0x2000) ; IMAGE_FILE_DLL
Return !(ErrorLevel := 7) ; not a valid DLL file
; Optional header -------------------------------------------------------------------------------------------------------------
; PE format (magic number): PE32 (32-bit) = 0x010B, PE32+ (64-bit) = 0x020B
; Read the optional header and advance the file pointer to the begin of the section headers.
DllFile.RawRead(RawBytes, SizeOfOptionalHeader)
Magic := NumGet(RawBytes, 0, "UShort") ; the state of the image file
Off_64 := (Magic = 0x020B) ? 16 : 0 ; additional offset for 64-bit, zero for 32-bit
SizeOfImage := NumGet(RawBytes, 56, "UInt") ; the size of the image as loaded into memory
OffSet := 92 + Off_64
If ((NumberOfRvaAndSizes := NumGet(RawBytes, Offset + 0, "UInt")) < 1) ; the number of data directory entries
|| ((ExportAddr := NumGet(RawBytes, Offset + 4, "UInt")) < 1) ; the address of the export table (RVA)
|| ((ExportSize := NumGet(RawBytes, Offset + 8, "UInt")) < 1) ; the size of the export table
Return !(ErrorLevel := 8) ; couldn't find an export table
; Section headers -------------------------------------------------------------------------------------------------------------
; The section data have to be 'loaded' to the relative virtual addresses defined in the section headers.
; Otherwise, the RVAs defined in the export table don't match the corresponding data.
; Read the section headers
SectionsLength := SizeOfSectionHdr * NumberOfSections
DllFile.RawRead(RawBytes, SectionsLength)
; 'Load' the sections.
VarSetCapacity(ImageData, SizeOfImage, 0) ; create a variable capable to store the sections data
Offset := 0
Loop, %NumberOfSections%
{
VirtualAddress := NumGet(RawBytes, Offset + 12, "UInt")
SizeOfRawData := NumGet(RawBytes, Offset + 16, "UInt")
PointerToRawData := NumGet(RawBytes, Offset + 20, "UInt")
DllFile.Pos := PointerToRawData
DllFile.RawRead(&ImageData + VirtualAddress, SizeOfRawData)
Offset += SizeOfSectionHdr
}
; Export table ----------------------------------------------------------------------------------------------------------------
ImageBase := &ImageData ; the address of the string buffer of ImageData is used as image base address.
EndOfSection := ExportAddr + ExportSize
ModNamePtr := NumGet(ImageBase + ExportAddr + 0x0C, "UInt") ; pointer to an ASCII string that contains the name of the DLL
OrdinalBase := NumGet(ImageBase + ExportAddr + 0x10, "UInt") ; starting ordinal number for exports in this image
FuncCount := NumGet(ImageBase + ExportAddr + 0x14, "UInt") ; number of entries in the export address table
NameCount := NumGet(ImageBase + ExportAddr + 0x18, "UInt") ; number of entries in the name pointer table
FuncTblPtr := NumGet(ImageBase + ExportAddr + 0x1C, "uint") ; pointer to the export address table
NameTblPtr := NumGet(ImageBase + ExportAddr + 0x20, "UInt") ; pointer to the export name pointer table
OrdTblPtr := NumGet(ImageBase + ExportAddr + 0x24, "UInt") ; pointer to the ordinal table
Exports := {Module: StrGet(ImageBase + ModNamePtr, "CP0")
, Total: FuncCount
, Named: NameCount
, OrdBase: OrdinalBase
, Bitness: (Magic = 0x020B) ? 64 : 32
, Functions: []}
Loop %NameCount%
{
NamePtr := NumGet(ImageBase + NameTblPtr, "UInt")
Ordinal := NumGet(ImageBase + OrdTblPtr, "UShort")
FnAddr := NumGet(ImageBase + FuncTblPtr + (Ordinal * 4), "UInt")
EntryPt := (FnAddr > ExportAddr) && (FnAddr < EndOfSection) ? StrGet(ImageBase + FnAddr, "CP0")
: Format("0x{:08X}", FnAddr)
Exports.Functions.Push({Name: StrGet(ImageBase + NamePtr, "CP0"), EntryPoint: EntryPt, Ordinal: Ordinal + OrdinalBase})
NameTblPtr += 4, OrdTblPtr += 2
}
VarSetCapacity(ImageData, 0) ; free the memory used to store the image data
Return Exports
}
- Delta Pythagorean
- Posts: 627
- Joined: 13 Feb 2017, 13:44
- Location: Somewhere in the US
- Contact:
Re: DLL Export Viewer
@just me
That's quite an interesting take on this project. I'll say I now know how to return errorlevel with a number instead of just returning a normal number.
That's quite an interesting take on this project. I'll say I now know how to return errorlevel with a number instead of just returning a normal number.
[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat
Re: DLL Export Viewer
Edit
- rewritten
- rewritten
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: DLL Export Viewer
Thanks @jNizM
Wish i'd seen this before trying to do it myself
Wish i'd seen this before trying to do it myself
Re: DLL Export Viewer
v2 release -> viewtopic.php?t=111097
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile