'2018-03-10
'2022-09-28
'Charles E V Pegge

'extract dll procedure names
'create unprototyped omniheader

uses console
'
'32.dll: kernel/user/gdi/oleaut/Comctl/Comdlg/shell/
'.dll:   Msvcrt"
string ff="Msvcrt"
string fi=ff+".dll"
string fo=ff+".inc"
sys hl=loadlibrary fi
'
if not hl
  printl "Unable to find " fi 
  goto done
endif
'
printl "filename " fi
sys  ps=hl
sys  *ph
word *pw
char*pc
'
@ph=ps+0x3c
@pw=ps+ph+0x18
'printl "magic: " hex pw
sys pcoff=ps+ph
int*sh
if pw=0x10b
  printl "32 bit"
  @ph=pcoff+0x78 'offset data here
  @sh=pcoff+0xf8
else
  printl "64 bit"
  @ph=pcoff+0x88
  @sh=pcoff+0x108
endif

printl "Offset of export section header table " hex ph

int*pl
'@pl=@ph+4
'printl "Length of export section header table " hex pl 
'
sys  pa    'returned from GetProcAddress
sys  pt    'address of string
int *px    'RVA names list
int *pq    'count of names
int *pn    'dereferencer
word*dn    'ordinal table entry
sys  fn    'function address
int  oo    'name list and function list strider
string fs  'number string
string bb  'output buffer
string ss  'composed declaration line
'
'CALCULATE DATA LOCATIONS
'
@px=ps+ph+0x0c   'RVA of name of table
@pc=ps+px        'name of table
@pq=ps+ph+0x18   'number of names
@px=ps+ph+0x20   'offset of names list
'
printl pc        'print name of table
bb=nuls pq*100   'allow a maximum of 100 bytes for each record
word*pb          'buffer position / and white space patcher
int le           'length of string
@pb=strptr bb    'set to start of buffer
'
'
'GENERATE EXTERN STATEMENT
'
ss="extern lib "+qu+fi+qu+cr
le=len(ss)
@pc=strptr ss
copy @pb,@pc, le 'patch in
@pb+=le          '
int i
'
for i=1 to pq        'each function in the export table
  '
  'GET THE NAME OF EACH FUNCTION
  '
  @pn=ps+px+oo       'address of function name
  @pc=ps+pn          'function name
  ss="! "+pc
  if right(ss,1)="A"
    le=len(ss)
    '
    'CREATE ALIAS NAME IN QUOTES
    '
    ss=left(ss,le-1)+" "+qu+pc+qu 'add quoted alias
  endif
  '
  'PATCH EACH DECLARATION INTO BUFFER
  '
  @pc=strptr ss
  le=len ss
  oo+=4            'stride for next DLL proc entry
  copy @pb,@pc, le 'patch in function name
  @pb+=le          '
  pb=0x0a0d        'patch in crlf
  @pb+=2           '
next
'
'CLOSE EXTERN BLOCK
'
ss="end extern"+cr
le=len(ss)
@pc=strptr ss
copy @pb,@pc, le 'patch in
@pb+=le
'
'FILE THE COMPLETED HEADER
'        '
le=@pb-strptr bb 'length of list
putfile fo, left bb,le
printl "saved as " fo
'
'RELEASE THE DLL
'
freelibrary hl
'
done:
=====
'
wait
