Page 1 of 1

PureLibrary reader - enumerate exported functions & descs

Posted: Mon Sep 21, 2015 10:00 am
by Keya
I was interested in enumerating which functions each PureLibrary has, with the idea being that we might possibly be able to use that to then crosscheck against the .asm file that PB generates to see if we can trim unused libraries?

This demo parses the PureLibrary file looking for each "PURE" section, then when it finds a "LIB" section it walks through those - they simply contains Function Name, Function Parameter info in some undocumented format i have no interest in that i just safely skip over, Parameter Count, and Function Description. It also detects which external libraries like DLLs it links to, and which other PureBasic libraries are dependencies, as it has to walk over this information anyway before it gets to the exported functions. :)

Sample output of x86 \PureLibraries\Http:

Code: Select all

Found Section @ 0x8, type=4BIL, size=941 bytes
2 external libraries linked
 EXTRNLIB:libcurl
 EXTRNLIB:ws2_32

PURELIBNAME=Http

2 PureLibraries imported
 PURELIB:Date
 PURELIB:Network

AbortHTTP [1 params]: (HttpConnection) - Abort the download of the specified HTTP connection.
FinishHTTP [1 params]: (HttpConnection) - Release the resources of the specified HTTP connection.
GetHTTPHeader [1 params]: (URL$) - Get the HTTP headers
GetURLPart [2 params]: (URL$, Parameter$) - Get the specific part of an URL.
HTTPProgress [1 params]: (HttpConnection) - Get the progress on the specified HTTP connection.
ReceiveHTTPFile [2 params]: (URL$, Filename$ [, Flags]) - Download a file from an URL.
ReceiveHTTPFile2 [3 params]: 
ReceiveHTTPMemory [1 params]: (URL$ [, Flags]) - Download a file from an URL to a memory buffer.
ReceiveHTTPMemory2 [2 params]: 
SetURLPart [3 params]: (URL$, Parameter$, Value$) - Set the specific part of an URL.
URLDecoder [1 params]: (URL$ [, Format]) - Returns the decoded URL$.
URLDecoder2 [2 params]: 
URLEncoder [1 params]: (URL$ [, Format]) - Returns the URL$ encoded to HTTP format.
URLEncoder2 [2 params]: 
14 total functions

Found Section @ 0x3B5, type=1TAD, size=12548 bytes

PureLibrary Reader.pb

Code: Select all

EnableExplicit

Procedure ReadPureLibSection(*pPureSect, lSize.l)   ;*pmem points to 'ERUP' magic bytes
  Protected cnt.i, sTmp.s, i.i, LastAddr.i, numfuncs.i, FuncParams.i
  Protected sFuncName.s, sFuncDesc.s
  Protected *pmem = *pPureSect + 20
  Protected sPureLibName.s, sPureInternalName.s
  LastAddr = *pPureSect + lSize
  sPureLibName = PeekS(*pmem,1024,#PB_Ascii)
  *pmem + Len(sPureLibName) + 1  
  While *pmem < LastAddr
    Select PeekA(*pmem)
      Case 01:  ;external libraries
        cnt = PeekA(*pmem+1)
        Debug(Str(cnt) + " external libraries linked")
        If cnt
          *pmem + 2
          For i = 1 To cnt
            sTmp = PeekS(*pmem,-1,#PB_Ascii)
            Debug (" EXTRNLIB:" + sTmp)
            *pmem + Len(sTmp) + 1          
          Next i
        Else
          *pmem + 2
        EndIf
      Case 02:  ;PureLibraries
        *pmem + 1
        sPureInternalName = PeekS(*pmem,-1,#PB_Ascii)
        Debug("PURELIBNAME=" + sPureInternalName)
        *pmem + Len(sPureInternalName)      
        cnt = PeekA(*pmem+1)
        Debug(Str(cnt) + " PureLibraries imported")
        If cnt
          *pmem + 2
          For i = 1 To cnt
            sTmp = PeekS(*pmem,-1,#PB_Ascii)
            Debug (" PURELIB:" + sTmp)
            *pmem + Len(sTmp) + 1          
          Next i
        Else
          *pmem + 2
        EndIf        
        While *pmem < LastAddr     ;Walk through each exported function
          sFuncName = PeekS(*pmem,-1,#PB_Ascii)
          *pmem + Len(sFuncName) + 1          
          FuncParams = PeekA(*pmem)
          *pmem + 5 + FuncParams ;skip the params
          sFuncDesc = PeekS(*pmem,-1,#PB_Ascii)          
          *pmem + Len(sFuncDesc) + 1          
          Debug(sFuncName + " [" + Str(FuncParams) + " params]: " + sFuncDesc)
          numfuncs + 1
        Wend
        Debug(Str(numfuncs) + " total functions") 
        ProcedureReturn
        
      Default:
        MessageRequester("Error","Parse error"): ProcedureReturn
    EndSelect     
  Wend
EndProcedure



Procedure.i ReadPureLibrary(sLibfile.s)
  Protected hFile.i, *pbuf, fLen.q, *plong.long, lSize.l, lType.l
  hFile = ReadFile(#PB_Any, sLibfile, #PB_File_SharedRead)
  If hFile = 0: ProcedureReturn -1: EndIf
  fLen = Lof(hFile)
  *pbuf = AllocateMemory(fLen)
  fLen = ReadData(hFile, *pbuf, fLen)
  CloseFile(hFile)
  *plong = *pbuf
  If PeekS(*plong,4,#PB_Ascii) <> "ERUP": ProcedureReturn -2: EndIf
  While PeekS(*plong,4,#PB_Ascii) = "ERUP"
    *plong + 4
    lSize = *plong\l
    *plong + 4
    lType = *plong\l
    Debug("Found Section @ 0x" + Hex(*plong - *pbuf) + ", type=" + PeekS(*plong,4,#PB_Ascii) + ", size=" + Str(lSize+12) + " bytes")
    If Left(PeekS(@lType+1,3,#PB_Ascii),3) = "BIL"   ;we only process the "LIB" section, not "DAT" or other
      ReadPureLibSection(*plong-8, lSize+12)
    EndIf
    Debug(#CRLF$)    
    *plong + lSize + 4
  Wend
EndProcedure



Define iRes.i
;iRes = ReadPureLibrary(#PB_Compiler_Home + "/PureLibraries/Clipboard")
iRes = ReadPureLibrary(#PB_Compiler_Home + "/PureLibraries/VectorDrawing")
;iRes = ReadPureLibrary(#PB_Compiler_Home + "/PureLibraries/Gadget")
 
Select iRes
  Case -1: Debug("Error - ReadFile failed")
  Case -2: Debug("Error - Not a PureLibrary")
EndSelect

MessageRequester("Done","Done")

Re: PureLibrary reader - enumerate exported functions & desc

Posted: Tue Feb 23, 2016 4:26 pm
by Kwai chang caine
A little bit late :oops:
Works great on W7 v5.40
Thanks for sharing 8)

Re: PureLibrary reader - enumerate exported functions & desc

Posted: Tue Feb 23, 2016 6:49 pm
by Denis
Nice code.

Some functions are not coded inside libraries, for exemple in Math :
Abs
Cos
Sin
Sqr
Tan

PB generates directly asm code for them.

Re: PureLibrary reader - enumerate exported functions & desc

Posted: Wed Feb 24, 2016 3:47 pm
by Lunasole
Interesting example. But generally I don't see a big problem that PB includes trash to executables, it is of course noticeable and ugly-looking on micro programs, but + - even several mb of exe size doesn't matters with larger projects. Maybe it even makes harder to reverse your program, but not sure with it :)

Re: PureLibrary reader - enumerate exported functions & desc

Posted: Thu Feb 25, 2016 4:54 am
by Keya
see also my PureLibrary Explorer tool