Page 1 of 2

List all exported functions in a dll or exe

Posted: Sun Mar 04, 2007 3:40 am
by srod
Hi,

similar to my coff dump utility posted earlier, the following procedure will fill a string array with the names of all the functions exported from a dll or indeed an exe.

Unlike my previous post, however, this is not my original work! :cry:

Instead I have converted some Powerbasic code: http://www.powerbasic.com/support/forum ... 01216.html

Code: Select all

;'DllFunctionDump'.
;-----------------
;   Stephen Rodriguez.
;   Created with Purebasic 4.02 for Windows.
;
;   Based on some code by Torsten Rienow;  http://www.powerbasic.com/support/forums/Forum7/HTML/001216.html

;   Date:  March 2007.
;
;   Platforms:  Windows only.  Tested on XP professional SP2.
;
;Licence.
;-------
;   You are not allowed to use this code or any derivative for any hacking (api hijacking)
;   tools.
;
;   No warranties... etc.
;******************************************************************************************
;
;The function GetDllFunctions() will retrieve all exported function names residing within 
;the specified dll/exe file.  The names are placed within a string array passed as a parameter 
;to the Procedure.
;The function returns a count of the number of functions retrieved.
;It will also return zero in the case of an error.
;
;The array will be redimensioned as appropriate,
;******************************************************************************************


#IMAGE_DOS_SIGNATURE = $5A4D
#IMAGE_NT_SIGNATURE = $4550

;The following structure is not already defined by PB,
Structure _IMAGE_SECTION_HEADER
  Name.b[8]    ;8 bytes for a null-padded section name. UTF 8 format.
  VirtualSize.l ;= 0
  VirtualAddress.l ; = 0
  SizeOfRawData.l 
  PointerToRawData.l
  PointerToRelocations.l
  PointerToLineNumbers.l ; = 0
  NumberOfRelocations.w
  NumberOfLineNumbers.w ; = 0
  Characteristics.l 
EndStructure



Procedure.l GetDllFunctions(filename.s,  strTable.s(1))
  Protected filesize, fileid, hFileMapping, filebase
  Protected *idh.IMAGE_DOS_HEADER, *inth.IMAGE_NT_HEADERS
  Protected *ExpDir.IMAGE_EXPORT_DIRECTORY, *section._IMAGE_SECTION_HEADER, *exsection._IMAGE_SECTION_HEADER
  Protected exportsStartRVA, exportsEndRVA, entryPointRVA
  Protected delta, *pFunctions.LONG, pNames, currentsymname$
  Protected flag, i, j, count, dirsize
  ;First job, check the filename.
    filesize = FileSize(filename)
    If filesize <=0 : ProcedureReturn 0 : EndIf
    fileid=ReadFile(#PB_Any, filename)
    If fileid = 0 : ProcedureReturn 0 : EndIf
  ;Create a file mapping object so that we can treat the dll as if it were in memory.
    hFileMapping = CreateFileMapping_(FileID(fileid), 0, #PAGE_READONLY, 0, 0, 0)
    If hFileMapping = 0 : CloseFile(fileid) : ProcedureReturn 0 : EndIf
  ;Map the file.
    FileBase = MapViewOfFile_(hFileMapping, #FILE_MAP_READ, 0, 0, 0)
    If FileBase  = 0
      CloseHandle_(hFileMapping)
      CloseFile(fileid)
      ProcedureReturn 0
    EndIf
    *idh=FileBase
    If *idh\e_magic = #IMAGE_DOS_SIGNATURE
      *inth=*idh + *idh\e_lfanew
      ;Check that the current process has access to the memory and the image is a valid pe dll/exe..
      If IsBadReadPtr_(*inth, SizeOf(IMAGE_NT_HEADERS)) = 0  And*inth\Signature = #IMAGE_NT_SIGNATURE
      ;Good to go!
      ;Determine the RVA of the exports data directory.
        exportsStartRVA = *inth\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress 
        exportsEndRVA = exportsStartRVA + *inth\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\Size 
        ;Get the first section.
          *section = *inth + SizeOf(IMAGE_FILE_HEADER)+4 + *inth\FileHeader\SizeOfOptionalHeader
        ;Identify the section containing the exports.  It is not always .edata !
          For i=1 To *inth\FileHeader\NumberOfSections
            If exportsStartRVA >= *section\VirtualAddress And exportsStartRVA < *section\VirtualAddress + *section\VirtualSize
              *exsection = *section
              Break        
            EndIf
            *section +SizeOf(_IMAGE_SECTION_HEADER)
          Next
        If *exsection
          ;Calculate the difference between the RVA's and the file offsets for the current section.
            delta = *exsection\VirtualAddress - *exsection\PointerToRawData
          ;Adjust the exportsStartRVa accordingly to give the file offset of the image export directory,
            *ExpDir = *idh + exportsStartRVA - delta
          *pFunctions  = *idh+ *ExpDir\AddressOfFunctions - delta
          pNames = *idh+ *ExpDir\AddressOfNames - delta
          For i = 0 To *ExpDir\NumberOfFunctions - 1
            ;Only add the function name if it actually points to some code!
              entryPointRVA = *pFunctions\l : *pFunctions + SizeOf(LONG)
              If entryPointRVA <> 0
                ;Add the name to the strTable() array and increase the count.
                  currentsymname$=PeekS(PeekL(pNames+i*4)- delta + *idh,-1, #PB_Ascii)
                  ReDim strTable.s(count)
                  strTable(count)=currentsymname$
                  count+1
              EndIf
          Next
        EndIf        
      EndIf
    EndIf
    UnmapViewOfFile_(FileBase)
    CloseHandle_(hFileMapping)
    CloseFile(fileid)
  ProcedureReturn count
EndProcedure


;Test.
Dim names.s(0)
num=GetDllFunctions("c:\windows\System32\kernel32.dll", names())
For i = 0 To num-1
  Debug names(i)
Next

Posted: Sun Mar 04, 2007 3:50 am
by netmaestro
Uh, teach? One question, why not:

Code: Select all

OpenLibrary(0, "kernel32.dll")
ExamineLibraryFunctions(0)
While NextLibraryFunction()
  cc+1
  Debug LibraryFunctionName()
Wend
Debug cc
Seems to produce identical output. I'm probably just missing something important.

Posted: Sun Mar 04, 2007 3:54 am
by srod
If that weren't so funny, I'd strangle myself! :oops:

What an arse head! I've spent several hours on this and didn't even think of looking at the PB library commands!

Doh!

Oh well, at least I learnt a lot about PE file structures along the way. That at least makes me feel a little better!

hehe. That's gotta be the dopiest thing ever!

Posted: Sun Mar 04, 2007 3:55 am
by netmaestro
:lol: :lol: :lol:

Not to worry, I've still got the boobyprize for my frigging timepicker.

Posted: Sun Mar 04, 2007 3:57 am
by srod
netmaestro wrote::lol: :lol: :lol:

Not to worry, I've still got the boobyprize for my frigging timepicker.
What happened with the timepicker?

Posted: Sun Mar 04, 2007 4:01 am
by netmaestro
I spent an entire day writing a heavily subclassed set of stringgadgets in a container that functioned as an updown-controlled timepicker gadget. A few days later I found the same thing could be done with:

Code: Select all

CreateWindowEx_(0,"SysDateTimePick32","",#WS_CHILD|#WS_VISIBLE|#DTS_TIMEFORMAT... etc.
That was a bummer.

Posted: Sun Mar 04, 2007 4:06 am
by netmaestro
Anyways, that's what you get for looking on the PowerBasic forum. You should have just known PureBasic does everything better!

Posted: Sun Mar 04, 2007 4:13 am
by srod
netmaestro wrote:You should have just known PureBasic does everything better!
As much as I want that statement to be true, alas I'd have to say that there are some things which are easier in Powerbasic than Purebasic. gui stuff is far easier in Purebasic, but Powerbasic does offer a greater range of datatypes which are actually more flexible when you get down to some serious api work.

Must admit that I do like Powerbasic and there are some great tips to be found in their forums.

Posted: Sun Mar 04, 2007 11:19 pm
by yrreti
netmaestro and srod, your the experts.

As long as were dealing with

List all exported functions in a dll or exe

Try this code and tear it apart if you like, or give me some suggestions.
I've been kind of busy lately and haven't had time to work on it lately.
Also my newby understanding about what's found at the address, well
maybe you can enlighten me more on how to use it? I'm really new at
some of this stuff. What I was really trying to do was to list the function
along with how many and what variables etc are used with each function.
It's easy to get the function name. But how to use it? I don't know?

This program also list some file info including http and ftp addresses
if found. Try it on some microsoft dll's.
'microsoft hidden phone home etc'
Actually that is how I have found and eliminated some spy ware in the
past by changing the internal address so it can't call home.

It opens up the results in notepad, so make sure your path to notepad
in this code is right.
I also added dashed lines to kind of align the data as different fonts
would cause it to be wavy.

-----watch out for line wrap----------
(also, I only have enable debugger checked in compiler options)

Code: Select all

;NOTE: CHANGE DRIVE AND PROGRAM LOCATIONS
;ACCORDING TO WHERE THEY ARE AT ON YOUR SYSTEM.

#SILENT_YNBOX = $C4   ;this gives you the silent yes no box

;Libfile.s ="c:\purebasic4_0\work\dlls\rmchart.dll"

agn:
   Libfile.s = OpenFileRequester ( "Select DLL file", "", "DLL (*.dll)|*.dll", 0 )
   
   If Trim(Libfile)=""
      End
   EndIf
   
   ;seperate path and file, and create info file with same name_info.txt
   
   ;GetFilePart retrieves the file part of full path. Eg: if full path is "C:\PureBasic\PB.exe", result will be "PB.exe"
   ;FileName$ = GetFilePart(FullPathName$)
   f$=GetFilePart(Libfile)
   
   ;GetPathPart retrieves path part of full path. Eg: if full path is "C:\PureBasic\PB.exe", result will be "C:\PureBasic\".
   ;Path$ = GetPathPart(FullPathName$)
   pth$ = GetPathPart(Libfile)
   
   f$=Left(f$,Len(f$)-4)+"_info.txt"
   
   File$=pth$+f$
   
   CreateFile(1,File$)
   WriteStringN(1,Libfile)
   WriteStringN(1,Space(15)+"(best viewed with  Font:Fixedsys or Courier  Style:Regular  Size:12)")
   WriteStringN(1,"  ")
   
   adrs=0
   dat$=""
   www_info$=""
   at_end=0
   If ReadFile(0,Libfile)
      Repeat
         adrs+1
         If at_end=0                ;Use to speed up file search until "VERSION_INFO" is found.
            car=ReadCharacter(0)    ;This method is needed to remove the nulls between characters.
            If car>31
               dat$=dat$+Chr(car)
               If Len(dat$)>100
                  dat$=Mid(dat$,70,999)
               EndIf
               
            EndIf
         Else
            car=ReadCharacter(0)
            If car>31 And car<127
               dat$=dat$+Chr(car)
               If Len(dat$)>100
                  dat$=Mid(dat$,60,999)
               EndIf
               
            EndIf
         EndIf
         
         If FindString(LCase(dat$),"http://",1)>0
            p=FindString(LCase(dat$),"http://",1)
            dat$=Mid(dat$,p,999)
            dat2$=""
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
            Until car<>0
            
            If car>31 And car<127
               dat$=dat$+Chr(car)
            EndIf
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
               dat2$=dat2$+" "+Str(car)
               If car>31 And car<127
                  dat$=dat$+Chr(car)
                  l=Len(dat$)
                  
               EndIf
               If Right(dat2$,5)="0 0 0"
                  car=1
               EndIf
               If Right(dat2$,5)="13 10"
                  car=1
               EndIf
            Until car=1
            la$=Hex(adrs-7)+"     "
            www_info$=www_info$+la$+dat$+"\"
            dat$=""
         EndIf
         
         If FindString(LCase(dat$),"www.",1)>0
            p=FindString(LCase(dat$),"www.",1)
            dat$=Mid(dat$,p,999)
            dat2$=""
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
            Until car<>0
            
            If car>31 And car<127
               dat$=dat$+Chr(car)
            EndIf
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
               dat2$=dat2$+" "+Str(car)
               If car>31 And car<127
                  dat$=dat$+Chr(car)
                  l=Len(dat$)
                  
               EndIf
               If Right(dat2$,5)="0 0 0"
                  car=1
               EndIf
               If Right(dat2$,5)="13 10"
                  car=1
               EndIf
            Until car=1
            
            If Len(dat$)>10
               la$=Hex(adrs-4)+"     "
               www_info$=www_info$+la$+dat$+"\"
            EndIf
            dat$=""
         EndIf
         
         If FindString(LCase(dat$),"ftp://",1)>0
            p=FindString(LCase(dat$),"ftp://",1)
            dat$=Mid(dat$,p,999)
            dat2$=""
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
            Until car<>0
            
            If car>31 And car<127
               dat$=dat$+Chr(car)
            EndIf
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
               dat2$=dat2$+" "+Str(car)
               If car>31 And car<127
                  dat$=dat$+Chr(car)
                  l=Len(dat$)
                  
               EndIf
               If Right(dat2$,5)="0 0 0"
                  car=1
               EndIf
               If Right(dat2$,5)="13 10"
                  car=1
               EndIf
            Until car=1
            la$=Hex(adrs-6)+"     "
            ftp_info$=ftp_info$+la$+dat$+"\"
            dat$=""
         EndIf
         
         If FindString(UCase(dat$), "VS_VERSION_INFO",1)>0
            p=FindString(UCase(dat$), "VS_VERSION_INFO",1)
            dat$=Mid(dat$,p,999)
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
            Until car<>0
            
            If car>31 And car<127
               dat$=dat$+Chr(car)
            EndIf
            
            Repeat
               adrs+1
               car=ReadCharacter(0)
               dat2$=dat2$+" "+Str(car)
               If car>31 And car<127
                  dat$=dat$+Chr(car)
                  l=Len(dat$)
                  
               EndIf
               If Right(dat2$,5)="0 0 0"
                  car=1
               EndIf
            Until car=1
            info$="VERSION_INFO  "+Mid(dat$,16,999)
            WriteStringN(1,"File location address: "+Hex(adrs-15))
            WriteStringN(1,info$)
            dat$=""
            dat2$=""
            at_end=1
         EndIf
         
         If at_end=1
            If FindString(LCase(dat$),"stringfileinfo",1)>0
               p=FindString(LCase(dat$),"stringfileinfo",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               got=0
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     got=1
                  EndIf
               Until got=1;car>0 And car<32
               
               info$="StringFileInfo  "+Mid(dat$,15,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"companyname",1)>0
               p=FindString(LCase(dat$),"companyname",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               
               info$="CompanyName  "+Mid(dat$,12,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"filedescription",1)>0
               p=FindString(LCase(dat$),"filedescription",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="FileDescription  "+Mid(dat$,16,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"fileversion",1)>0
               p=FindString(LCase(dat$),"fileversion",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="FileVersion  "+Mid(dat$,12,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"internalname",1)>0
               p=FindString(LCase(dat$),"internalname",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="InternalName  "+Mid(dat$,13,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"legalcopyright",1)>0
               p=FindString(LCase(dat$),"legalcopyright",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="LegalCopyright  "+Mid(dat$,15,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"originalfilename",1)>0
               p=FindString(LCase(dat$),"originalfilename",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="OriginalFilename  "+Mid(dat$,17,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"productname",1)>0
               p=FindString(LCase(dat$),"productname",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="ProductName  "+Mid(dat$,12,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"productversion",1)>0
               p=FindString(LCase(dat$),"productversion",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="ProductVersion  "+Mid(dat$,15,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"varfileinfo",1)>0
               p=FindString(LCase(dat$),"varfileinfo",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
               Until car=1
               info$="VarFileInfo  "+Mid(dat$,15,999)
               WriteStringN(1, info$)
               dat$=""
            EndIf
            
            If FindString(LCase(dat$),"translation",1)>0
               p=FindString(LCase(dat$),"translation",1)
               dat$=Mid(dat$,p,999)
               dat2$=""
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
               Until car<>0
               
               If car>31 And car<127
                  dat$=dat$+Chr(car)
               EndIf
               
               Repeat
                  adrs+1
                  car=ReadCharacter(0)
                  dat2$=dat2$+" "+Str(car)
                  If car>31 And car<127
                     dat$=dat$+Chr(car)
                     l=Len(dat$)
                     
                  EndIf
                  If Right(dat2$,5)="0 0 0"
                     car=1
                  EndIf
                  If Right(dat2$,5)="4 4 0"
                     car=1
                  EndIf
               Until car=1
               info$="Translation  "+Mid(dat$,15,999)
               WriteStringN(1, info$)
               dat$=""
               at_end=0
            EndIf
            
         EndIf
         
      Until Eof(0)<>0
      
      CloseFile(0)
      Delay(1000)
      
   EndIf
   
   If Len(www_info$)>0
      WriteStringN(1, " ")
      WriteStringN(1, "Location address      File http info:")
      If FindString(www_info$,"\",1)>0
         While FindString(www_info$,"\",1)>0
            p=FindString(www_info$,"\",1)
            l$=Left(www_info$,p-1)
            WriteStringN(1, l$)
            www_info$=Mid(www_info$,p+1,999)
         Wend
         
      Else
         WriteStringN(1, www_info$)
      EndIf
   EndIf
   
   If Len(ftp_info$)>0
      WriteStringN(1, " ")
      WriteStringN(1, "Location address      File ftp info:")
      If FindString(ftp_info$,"\",1)>0
         While FindString(ftp_info$,"\",1)>0
            p=FindString(ftp_info$,"\",1)
            l$=Left(ftp_info$,p-1)
            WriteStringN(1, l$)
            ftp_info$=Mid(ftp_info$,p+1,999)
         Wend
         
      Else
         WriteStringN(1, ftp_info$)
      EndIf
   EndIf
   
   WriteStringN(1, "  ")
   WriteStringN(1, "  ")
   
   OpenLibrary(0,Libfile)
   Delay(1000)

   WriteStringN(1,"See what functions this version offers")
   WriteStringN(1," ")
   WriteStringN(1,"FN #"+Space(3)+"Function Address"+Space(2)+"Function Name"+Space(30)+"Hex Values Found at Address")
   
   n=1
      
   ;Result = ExamineLibraryFunctions(#Library)
   ;To examine the functions contained in a library.
   If ExamineLibraryFunctions(0)
      
      ;Result = NextLibraryFunction()
      ;Allows you to step through the functions in the library
      While NextLibraryFunction()
         
         ;Result$ = LSet(String$, Length [, Character$])  eg: , 40,"_") = 40 _ characters added.
         
         ;Result$ = LibraryFunctionName()
         ;Returns the name of the function in the library currently being examined
         lfn$ = LSet(LibraryFunctionName(), 40,"_")
         
         ;Result.l = LibraryFunctionAddress()
         ;Returns the address of the function in the library currently being examined.
         
         ;Text$ = PeekS(*MemoryBuffer [, Length [, Flags]])
         ;Very useful to read a string at the specified memory address.
         ;The string should be ended by a '0' character, else it will
         ;read the memory until a '0' character is encounter.
         
         ;Text$ = PeekS(LibraryFunctionAddress())
         ;Text$ = PeekS(LibraryFunctionAddress(),-1,#PB_UTF8)
         ;Text$ = PeekS(LibraryFunctionAddress(),-1,#PB_Unicode)
         Text$ = PeekS(LibraryFunctionAddress(),-1,#PB_Ascii)
         
         n$ = LSet(Str(n), 10,"_")
                  
         ;hex #
         ;lfa$ = Str(LibraryFunctionAddress())
         lfa = LibraryFunctionAddress()
         lfa$=Hex(lfa)
         lfa$ = LSet(lfa$, 15,"_")
         
         lfnd$=LSet(n$+lfa$+lfn$,63,"_")
         
         ;CallDebugger
         ;convert text to hex values
         text3$=""
         For a =1 To Len(text$)
            a$=Mid(text$,a,1)
            ha=Asc(a$)
            ha$=Hex(ha)
            If Len(ha$)<2
               ha$="0"+ha$
            EndIf
            text3$=text3$+ha$+" "
         Next a
         text$=text3$
         
         If Len(Text$)>54
            fl=0
            While Len(Text$)>54
               LText$=Left(Text$,54)
               If fl=0
                  WriteStringN(1,lfnd$+LText$)
                  fl=1
               EndIf
               Text$=Mid(Text$,55,99999)
               
               Text2$ = LSet("  ", 28,"_")+" continued"+LSet(" ", 25,"_")+Left(Text$,54)
               WriteStringN(1,Text2$)
               Text$=Mid(Text$,55,99999)
            Wend
            If Trim(text$)<>""
               Text2$ = LSet("  ", 28,"_")+" continued"+LSet(" ", 25,"_")+Text$
               WriteStringN(1,Text2$)
            EndIf
            WriteStringN(1," ")  ;add divider space
            
         Else
            WriteStringN(1,lfnd$+Text$)
         EndIf
         
         n+1
         Delay(10)
      Wend
      
      CloseFile(1)
      
   EndIf
   
   ;CloseLibrary(0)
   Delay(10)
   
   RunProgram("c:\windows\notepad.exe" , f$, pth$, #PB_Program_Wait)
   
   result=MessageRequester(" ","Examine another DLL file ? ",#PB_MessageRequester_YesNo);#SILENT_YNBOX)
   If result<>7
      ;CloseLibrary(0)
      Goto agn
   EndIf
   End
   

Posted: Sun Mar 04, 2007 11:29 pm
by srod
Hi,

just to say that dll's do not contain information on the parameters of the exported functions, so you'll search in vain for these! :)

Posted: Mon Mar 05, 2007 12:11 am
by SFSxOI
srod:

Gives me an Invalid memory error with this line:

Code: Select all

currentsymname$=PeekS(PeekL(pNames+i*4)- delta + *idh,-1, #PB_Ascii) 
If I try to do any .dll except for kernel32.dll

Posted: Mon Mar 05, 2007 12:16 am
by srod
Works okay here on sqlite3.dll, every windows dll I try, some dll's created with PB!

Try:

Code: Select all

;'DllFunctionDump'. 
;----------------- 
;   Stephen Rodriguez. 
;   Created with Purebasic 4.02 for Windows. 
; 
;   Based on some code by Torsten Rienow;  http://www.powerbasic.com/support/forums/Forum7/HTML/001216.html 

;   Date:  March 2007. 
; 
;   Platforms:  Windows only.  Tested on XP professional SP2. 
; 
;Licence. 
;------- 
;   You are not allowed to use this code or any derivative for any hacking (api hijacking) 
;   tools. 
; 
;   No warranties... etc. 
;****************************************************************************************** 
; 
;The function GetDllFunctions() will retrieve all exported function names residing within 
;the specified dll/exe file.  The names are placed within a string array passed as a parameter 
;to the Procedure. 
;The function returns a count of the number of functions retrieved. 
;It will also return zero in the case of an error. 
; 
;The array will be redimensioned as appropriate, 
;****************************************************************************************** 


#IMAGE_DOS_SIGNATURE = $5A4D 
#IMAGE_NT_SIGNATURE = $4550 

;The following structure is not already defined by PB, 
Structure _IMAGE_SECTION_HEADER 
  Name.b[8]    ;8 bytes for a null-padded section name. UTF 8 format. 
  VirtualSize.l ;= 0 
  VirtualAddress.l ; = 0 
  SizeOfRawData.l 
  PointerToRawData.l 
  PointerToRelocations.l 
  PointerToLineNumbers.l ; = 0 
  NumberOfRelocations.w 
  NumberOfLineNumbers.w ; = 0 
  Characteristics.l 
EndStructure 



Procedure.l GetDllFunctions(filename.s,  strTable.s(1)) 
  Protected filesize, fileid, hFileMapping, filebase 
  Protected *idh.IMAGE_DOS_HEADER, *inth.IMAGE_NT_HEADERS 
  Protected *ExpDir.IMAGE_EXPORT_DIRECTORY, *section._IMAGE_SECTION_HEADER, *exsection._IMAGE_SECTION_HEADER 
  Protected exportsStartRVA, exportsEndRVA, entryPointRVA 
  Protected delta, *pFunctions.LONG, *pNames.LONG, currentsymname$ 
  Protected flag, i, j, count, dirsize 
  ;First job, check the filename. 
    filesize = FileSize(filename) 
    If filesize <=0 : ProcedureReturn 0 : EndIf 
    fileid=ReadFile(#PB_Any, filename) 
    If fileid = 0 : ProcedureReturn 0 : EndIf 
  ;Create a file mapping object so that we can treat the dll as if it were in memory. 
    hFileMapping = CreateFileMapping_(FileID(fileid), 0, #PAGE_READONLY, 0, 0, 0) 
    If hFileMapping = 0 : CloseFile(fileid) : ProcedureReturn 0 : EndIf 
  ;Map the file. 
    FileBase = MapViewOfFile_(hFileMapping, #FILE_MAP_READ, 0, 0, 0) 
    If FileBase  = 0 
      CloseHandle_(hFileMapping) 
      CloseFile(fileid) 
      ProcedureReturn 0 
    EndIf 
    *idh=FileBase 
    If *idh\e_magic = #IMAGE_DOS_SIGNATURE 
      *inth=*idh + *idh\e_lfanew 
      ;Check that the current process has access to the memory and the image is a valid pe dll/exe.. 
      If IsBadReadPtr_(*inth, SizeOf(IMAGE_NT_HEADERS)) = 0  And*inth\Signature = #IMAGE_NT_SIGNATURE 
      ;Good to go! 
      ;Determine the RVA of the exports data directory. 
        exportsStartRVA = *inth\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress 
        exportsEndRVA = exportsStartRVA + *inth\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\Size 
        ;Get the first section. 
          *section = *inth + SizeOf(IMAGE_FILE_HEADER)+4 + *inth\FileHeader\SizeOfOptionalHeader 
        ;Identify the section containing the exports.  It is not always .edata ! 
          For i=1 To *inth\FileHeader\NumberOfSections 
            If exportsStartRVA >= *section\VirtualAddress And exportsStartRVA < *section\VirtualAddress + *section\VirtualSize 
              *exsection = *section 
              Break        
            EndIf 
            *section +SizeOf(_IMAGE_SECTION_HEADER) 
          Next 
        If *exsection 
          ;Calculate the difference between the RVA's and the file offsets for the current section. 
            delta = *exsection\VirtualAddress - *exsection\PointerToRawData 
          ;Adjust the exportsStartRVa accordingly to give the file offset of the image export directory, 
            *ExpDir = *idh + exportsStartRVA - delta 
          *pFunctions  = *idh+ *ExpDir\AddressOfFunctions - delta 
          *pNames = *idh+ *ExpDir\AddressOfNames - delta 
          For i = 0 To *ExpDir\NumberOfFunctions - 1 
            ;Only add the function name if it actually points to some code! 
              entryPointRVA = *pFunctions\l : *pFunctions + SizeOf(LONG) 
              If entryPointRVA <> 0 
                ;Add the name to the strTable() array and increase the count. 
                  If *pNames\l
                    currentsymname$=PeekS(*pNames\l- delta + *idh,-1, #PB_Ascii) 
                    ReDim strTable.s(count) 
                    strTable(count)=currentsymname$ 
                    count+1 
                  EndIf
              EndIf 
            *pNames+SizeOf(LONG)
          Next 
        EndIf        
      EndIf 
    EndIf 
    UnmapViewOfFile_(FileBase) 
    CloseHandle_(hFileMapping) 
    CloseFile(fileid) 
  ProcedureReturn count 
EndProcedure 


;Test. 
Dim names.s(0) 
num=GetDllFunctions("user32.dll", names()) 
For i = 0 To num-1 
  Debug names(i) 
Next 


Posted: Mon Mar 05, 2007 12:32 am
by SFSxOI
second example, had to put in the complete path to the user32.dll. Seems to work with the standard system .dll's like user32.dll and kernel32.dll but when you start to do something like dwmapi.dll it crashes. So...i'm using Vista, maybe that has something to do with it. back to the dll2PB importer. Nice code though. Thank You :)

Posted: Mon Mar 05, 2007 12:34 am
by srod
Ah, but this is the dopiest code I've ever put together! Try netmaestro's code above which uses the PB library commands, see if that crashes on the particular dll you mentioned?

Posted: Mon Mar 05, 2007 12:39 am
by srod
The method posted by nemaestro above which uses the purebasic library commands also crashes with dwmapi.dll.