#include "llmod.as" #include "listview.as" ;------------------------------------------------------------ #module #deffunc setdatafile val mref v1,24 sdim file,256 exist v1 : if strsize=-1 { dialog "ファイル "+v1+" が見つかりません" dialog "exe",16 if stat=0 : end file=refstr v1=file }else file=v1 return #deffunc gdata 1 mref v1,16 mref v2,1 mref v3,2 bload file,v1,v2,v3 return #global ;------------------------------------------------------------ ; ;HSPの使っているAPIをリストビューに表示するプログラム ; #define LIST_SORT 0 #define LIST_LAST $7FFFFFFF cls 1 sdim file, 256 sdim s, 1024*64 file=exedir+"\\"+"hsprt" file=exedir+"\\"+"hsp2.exe" setdatafile file listview winx-6,winy/5-30,1 listaddcl 0,"file->"+file,winx-30 ;Read DOS signature gdata sign,2,0 wpeek s,sign if s!"MZ" : dialog "This file is invalid execute." : stop ; ---------- Read address of new exe header ---------- gdata new_hdr,4,$3C listadd LIST_LAST, "DOS SIGNATURE IS ->"+s listadd LIST_LAST, "NEW HEADER ADDRESS->"+new_hdr ; ---------- Read PE signature ---------- gdata pe_sign,4,new_hdr wpeek s,pe_sign ; ---------- Read number of section ---------- file_hdr=new_hdr+4 gdata n_sect,2,file_hdr+2 ; ---------- Read image base ---------- #define IMAGE_SIZEOF_FILE_HEADER 20 opt_hdr=file_hdr+IMAGE_SIZEOF_FILE_HEADER gdata imgbase,4,opt_hdr+$1C h=imgbase str h,16 listadd LIST_LAST, "PE SIGNATURE IS->"+s listadd LIST_LAST, "NUMBER OF SECTIONS->"+n_sect listadd LIST_LAST, "IMAGE BASE->0x"+h ; ---------- Read virtual address of import section ---------- #define IMGDIRENT_IMPORT 1 gdata import_address,4,opt_hdr+$60+(8*IMGDIRENT_IMPORT) h=import_address str h,16 listadd LIST_LAST, "import address section virtual address->0x"+h ; ---------- Read virtual address of import address table section ---------- #define IMGDIRENT_IMPORT_ADDRESS_TABLE 12 gdata import_tbl_addr,8,opt_hdr+$60+(8*IMGDIRENT_IMPORT_ADDRESS_TABLE) import_tbl_addr_size=import_tbl_addr.1 h=import_tbl_addr str h,16 listadd LIST_LAST, "import address table section virtual address->0x"+h+" size->"+import_tbl_addr_size #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 sect_hdr=opt_hdr+IMAGE_SIZEOF_NT_OPTIONAL_HEADER sdim sct, 1024 repeat n_sect await ; ---------- Read section header ---------- gdata s_hdr,$18,sect_hdr+(cnt*40) peek s,s_hdr sct+=s+" " if (s_hdr.3<=import_tbl_addr)&(s_hdr.3+s_hdr.4-1>=import_tbl_addr) { import_tbl_addr_offset=s_hdr.5+(import_tbl_addr-s_hdr.3) h=import_tbl_addr_offset str h,16 listadd LIST_LAST, "import address table offset=0x"+h+"("+s+")" list_n+ } loop listadd LIST_LAST, sct sdim names,1024*64 last_y=csry if LIST_SORT { ;ソート listview winx-6,winy/5*2,1+8+$10+$8000+$4000000+$200000 lst=stat insaft=0 }else{ ;ソートしない listview winx-6,winy/5*2,1+8+$8000+$4000000+$200000 lst=stat dup insaft,n } listaddcl 0,"Function Name",200 listaddcl 1,"Address",,1 listaddcl 2,"File offset",,1 listaddcl 3,"Ordinal",,1 n=0 sdim f, 1024 repeat -1 await ; ---------- Read import function address ---------- gdata impfunc_addr,4,import_tbl_addr_offset+(cnt*4) if cnt*4=import_tbl_addr_size : break if impfunc_addr { addr=import_tbl_addr_offset+(impfunc_addr-import_tbl_addr)+2 gdata _f,32,addr ;手抜き peek f,_f listadd insaft,f ;function name idx=stat h=import_tbl_addr+(cnt*4) + imgbase str h,16 listadd idx,"0x"+h,1 ;address h=impfunc_addr str h,16 listadd idx,"0x"+h,2 ;file offset n+ listadd idx,""+n,3 ;ordinal } loop listaddcl 4,"total:"+n,,2 _objsel lst listsel 0 y=csry objsize 200,30 button "関数名をmesboxで見る",view_with_mesbox pos 230,y : chkbox "選択されているもののみ",only_selected objsize 140,30 pos 430,y : chkbox "#defineを付ける",add_define objsize 30,30 pos 600,y : button "",open_notepad sdim funcs,1024*32 getptr pfuncs,funcs h=winy-csry-30 pos 0,csry mesbox funcs,winx-6,h,1 #define MESBOX_ID 4 stop *view_with_mesbox gosub make_list objprm MESBOX_ID,funcs stop *open_notepad gosub make_list exec "notepad.exe" dllproc "GetForegroundWindow",prm,0,D_USER #define GW_CHILD 5 #define GW_HWNDNEXT 2 #define GW_HWNDPREV 3 prm=stat,GW_CHILD dllproc "GetWindow",prm,2,D_USER #define WM_SETTEXT 12 prm=stat,WM_SETTEXT,0,pfuncs sendmsg prm stop *make_list funcs="" notesel funcs if only_selected { i=-1 n=0 repeat -1 listget i,i,,2 if i=-1 : break listget s,i,5 listget ss,i,5,,1 gosub s_format noteadd s n+ loop noteadd "選択された関数の数 ("+n+"個)",0 }else{ listmax max noteadd file+"で使っているWin32API ("+max+"個)\n",0,1 repeat max listget s,cnt,5 listget ss,cnt,5,,1 gosub s_format noteadd s loop } return *s_format #define TAB_STOP 8 if add_define : s="#define\t"+s strlen l,s a=l&(TAB_STOP-1) if a : s+="\t" : l+=TAB_STOP-a repeat -1 if l>24 : break s+="\t" l+=TAB_STOP loop s+=ss return ; ; loadlib.dllを使ってくださっているWin32APIに詳しい人へ ; ; *** このプログラムで表示される関数のアドレスについて *** ; ; dllの関数を使う場合、普通はdllをロードしてGetProcAddressで関数のアドレスを ; 取得しなければなりませんが、実行ファイルが使っているWin32API関数はその一連の ; 操作を行わなくても使うことができます。 ; 例えば、MessageBoxAはHSPで既に使われているので、user32.dllをロードしなくても ; 以下のようにして使うことができます。 ; ; #include "llmod.as" ; ; ;この値はHSP ver2.5β10 hsp2.exe での値です ; #define MESSAGEBOX_ADR 0x417188 ; ; ll_peek4 func,MESSAGEBOX_ADR ; ; prm=0 ; getptr prm.1,m ; getptr prm.2,c ; prm.3=1+$20 ; ; c="caption" ; m="message" ; ; ll_callfunc prm,4,func ; ; 但し、hsp2.exeとhsprtでは関数のアドレスが違うので、HSPスクリプトエディタから ; F5キーで実行する時と実行ファイルを作る時では違うアドレスを指定しなければ ; ならないことに注意してください。各ファイルがバージョンアップしたときも ; アドレスが変わることがあることにも注意してください。 ; 例のようにアドレス値を#defineしたものをファイルに作っておき、#include命令で ; 取り込むファイルを使い分けると便利でしょう。 ; ; HSPで既に使われているAPIなのに、dllをロードしなければならないのは納得いかない ; という人は試してみてください。 ;