goo blog サービス終了のお知らせ 
goo

PEフォーマット .rsrcセクション サンプル





◆サンプル
「.rsrc」セクション内のデータを取得します。
アイコンの最初の一つのアイコンと一つのイメージを取得します。
また、その情報を元に実行フォルダに、アイコンを作成します。
テストとして、実行ファイルのアイコンを変換しています。
ですが、不完全ですので必要のない複成された実行ファイルで
テストしてください。
※API関数を使えばもっと簡単にコーディングできますが、
あくまで構造を知る上でのサンプルです。

実行結果
サンプル ソースコード
/////////////////////////////////////////////////////////////////
//インクルード
#include "user32.as"
#include "kernel32.as"
#include "shell32.as"

/////////////////////////////////////////////////////////////////
//定義
#define		TITLENAME	".rsrcセクション"
#define		SAVE_ICON_NAME	dir_exe+"\\\\save_icon.ico"

/////////////////////////////////////////////////////////////////
//変数
	sdim string    ,10240
	sdim string2   ,10240
	sdim filename  ,1024
	sdim iconfile  ,1024
	sdim icon_data ,22
	sdim icon_bmp  ,10240
	sdim data      ,1024
	dim  rsrc_data ,10
	dim  rsc_dir   ,4
	dim  rsc_dir_e ,2
	dim  rsc_data_e,4
	dim  rsc_data_e2,4
	dim  rsc_data_addr,32
	dim  icon_cnt  ,2
	dim  icon_addr ,4
	sdim rsc_data  ,1024 , 32
	sdim rsc_name  ,1024 , 32
	rsc_name(0)="?","RT_CURSOR","RT_BITMAP","RT_ICON","RT_MENU","RT_DIALOG"
	rsc_name(6)="RT_STRING","RT_FONTDIR","RT_FONT","RT_ACCELERATOR","RT_RCDATA"
	rsc_name(11)="RT_MESSAGETABLE","RT_GROUP_CURSOR","?","RT_GROUP_ICON","?"
	rsc_name(16)="RT_VERSION","RT_DLGINCLUDE","?","RT_PLUGPLAY","RT_VXD"
	rsc_name(21)="RT_ANICURSOR","RT_ANIICON","RT_HTML","RT_MANIFEST"

/////////////////////////////////////////////////////////////////
//メイン
	screen 0,300,300
	title TITLENAME : color 200,200,200:boxf
	objsize 100,30
	pos 0,0  : button gosub "EXE読込",*LoadFile
	pos 100,0: button gosub "ICO読込",*Load_Icon
	pos 200,0: button gosub "書換",*change_icon
	pos 0,100 : mesbox data,300,200,5
	pos 140,60:color:mes "⇒"
	onexit *soft_end
stop

/////////////////////////////////////////////////////////////////
//ファイル読込
*LoadFile
	btnflag=1000
	dialog "exe;*.dll",16,"" : if stat!=1 : return
	filename = refstr
*LoadFile2
	tmp=0 : data="" : notesel data
	/////////////////////////////////////////////////////////
	//①WIN32アプリかどうか
	bload filename , tmp , 2 , 0x00
	if tmp!=0x5a4d{
		dialog "WIN32アプリではありません",,"中止"
		return
	}
	/////////////////////////////////////////////////////////
	//②MS-DOSヘッダサイズ取得
	bload filename,tmp,2,0x8
	ms_dos=tmp*16
	/////////////////////////////////////////////////////////
	//③PEヘッダアドレス取得
	bload filename,pe,4,0x3c
	dim tmp
	bload filename,tmp,2,pe
	if tmp!=0x4550{
		dialog "PEフォーマットではありません",,"中止"
		return
	}
	/////////////////////////////////////////////////////////
	//④セクション名の取得
	sec=pe+0xf8 : tmp=0
	repeat -1
		bload filename,string,8,sec
		if string="" : break
		if string=".rsrc"{
			tmp=1
			bload filename,rsrc_data,40,sec
			break
		}
		sec+=40 : wait 1
	loop
	if tmp=0 : dialog ".rsrcセクションが見つかりませんでした" :return

	noteadd "[.rsrc]セクション",-1
	noteadd ""+rsrc_data(4)+"byte",-1
	noteadd "address="+strf("0x%08x",rsrc_data(5)),-1
	/////////////////////////////////////////////////////////
	//⑤.rsrcセクションテーブル取得
	//リソースディレクトリ 構造例
	//1.リソースの種類を取得(アイコン、画像、メニュー等)
	//一つのIMAGE_RESOURCE_DIRECTORY構造体
	//複数のIMAGE_RESOURCE_DIRECTORY_ENTRY構造体
	//2.1で取得したリソースの種類の各アイテムIDを取得
	//一つのIMAGE_RESOURCE_DIRECTORY構造体(16byte)
	//複数のIMAGE_RESOURCE_DIRECTORY_ENTRY構造体(8byte)
	//:
	//:1で取得したリソースの数を繰り返し
	//3.リソースの言語(日本語:1041 英語:1033)
	//一つのIMAGE_RESOURCE_DIRECTORY構造体
	//複数のIMAGE_RESOURCE_DIRECTORY_ENTRY構造体

	sec=rsrc_data(5)
	noteadd "",-1
	// ※flagはIDの総数
	// ※entry_cntはIDの数
	// ※icon_cntはアイコンリソースの位置
	flag=0:entry_cnt=0:icon_cnt=-1,-1:rsc_cnt=0

	repeat -1
		//ディレクトリ部分読込
		bload filename ,rsc_dir,16,sec
		noteadd "--------------------------------------------",-1
		if flag=0:noteadd "①リソースの種類を取得"
		if flag!=0{
			if flag>=cnt{
				noteadd "②①で取得したリソースの種類の各アイテムIDを取得",-1
				string=rsc_data(cnt-1)
				noteadd "リソースの種類 : "+string,-1
			}
			//RT_ICONの時
			if string="RT_ICON" && icon_cnt(0)=-1:icon_cnt(0)=rsc_cnt

			//RT_GROUP_ICONの時
			if string="RT_GROUP_ICON" && icon_cnt(1)=-1{
				icon_cnt(1)=rsc_cnt
			}
		}
		if flag!=0 && cnt>=flag+1:noteadd "③リソースの言語(日本語:1041 英語:1033)",-1

		noteadd "name_cnt="+wpeek(rsc_dir,12)+" id_cnt="+wpeek(rsc_dir,14),-1
		entry_cnt=wpeek(rsc_dir,12)+wpeek(rsc_dir,14)
		sec+=16
		//ディレクトリエントリー部分読込
		repeat entry_cnt
			bload filename , rsc_dir_e ,8 , sec 

			//リソースの型かIDを取得
			if rsc_dir_e(0)&0x80000000{	//文字列の場合
				tmp=(rsc_dir_e(0)&0x7fffffff)+rsrc_data(5)
				dim tmp
				tmp2=(rsc_dir_e(0)&0x7fffffff)+rsrc_data(5)
				bload filename,tmp,2,tmp2 : tmp2+=2
				bload filename,string2,tmp*2,tmp2
				WideCharToMultiByte 0,0,varptr(string2),tmp,varptr(string),1024,0,0
				poke string,tmp,0
				if flag =0:rsc_data(cnt)=string
				noteadd strf("%03d : ",cnt+1)+string,-1

				if flag!=0:rsc_cnt++
			}
			else{				//数値(ID)の場合
				if flag=0{		//リソースの型取得
					if  25>rsc_dir_e(0){
						rsc_data(cnt)=rsc_name(rsc_dir_e(0))
					}
					else{
						rsc_data(cnt)="ID : "+rsc_dir_e(0)
					}
					noteadd strf("%03d : ",cnt+1)+rsc_data(cnt),-1
				}
				else{			//ID取得
					noteadd strf("%03d ID : ",cnt+1)+rsc_dir_e(0),-1
					rsc_cnt++				}
			}

			sec+=8 : wait 1
		loop

		if rsc_dir_e(1)&0x80000000{	//テーブルデータ有
			noteadd "",-1
		}
		else{				//テーブル終了
			//セクションテーブルのオフセット取得
			sec=(rsc_dir_e(1)&0x7fffffff)+rsrc_data(5)
			break
		}
		wait 1
		if flag=0:flag=entry_cnt
	loop

	//アイコン読込失敗
	if icon_cnt(0)=-1 || icon_cnt(1)=-1{
		dialog "アイコン読込失敗"
		goto *load_err
	}

	//⑥.rsrcセクションデータ取得
	noteadd "",-1
	noteadd "--------------------------------------------",-1
	noteadd "アイコンデータ取得中・・・",-1

	//今回は、最初のアイコン情報のみ取得
	//RT_GROUP_ICON
	//ICONDIR構造体取得
	icon_addr(1)=sec+(icon_cnt(1)*16)
	bload filename,rsc_data_e,16,icon_addr(1)
	if rsc_data_e(0)&0x80000000{
		//スルー
	}
	else{
		tmp=rsc_data_e(0)-rsrc_data(3)+rsrc_data(5)
		bload filename,icon_data,rsc_data_e(1),tmp
	}

	noteadd "リソースの型(1 アイコン) : "+wpeek(icon_data,2)
	noteadd "イメージの数        : "+wpeek(icon_data,4)
	//ICONDIRENTRY構造体取得
	noteadd "イメージの幅        : "+peek(icon_data,6)
	noteadd "イメージの高さ       : "+peek(icon_data,7)
	noteadd "イメージの色数(256以上は0) : "+peek(icon_data,8)
	noteadd "color planes        : "+wpeek(icon_data,10)
	noteadd "1ピクセル当りのドット数   : "+wpeek(icon_data,12)
	dupptr tmp,varptr(icon_data)+14,4
	noteadd "アイコンファイルサイズ   : "+tmp
	dupptr tmp,varptr(icon_data)+18,4
	noteadd "BITMAPINFOHEADERまでのOFFSET: "+tmp
	//RT_ICON
	icon_addr(0)=sec+(icon_cnt(0)*16)
	bload filename,rsc_data_e2,16,icon_addr(0)
	if rsc_data_e(0)&0x80000000{
		//スルー
	}
	else{
		icon_addr(2)=rsc_data_e2(0)-rsrc_data(3)+rsrc_data(5)
		bload filename,icon_bmp,rsc_data_e2(1),icon_addr(2)
	}

	//BITMAPINFOHEADER構造体
	dupptr tmp,varptr(icon_bmp)+4,4
	noteadd "イメージの横サイズ(ピクセル): "+tmp
	dupptr tmp,varptr(icon_bmp)+8,4
	noteadd "イメージの縦サイズ(ピクセル): "+tmp

	//アイコンファイルとして保存
	if btnflag=1000{
		wpoke icon_data,0,0:wpoke icon_data,2,1:wpoke icon_data,4,1
		lpoke icon_data,14,rsc_data_e2(1):lpoke icon_data,18,22
		bsave SAVE_ICON_NAME,icon_data,22
		bsave SAVE_ICON_NAME,icon_bmp,rsc_data_e2(1),22
		noteadd "",-1
		noteadd SAVE_ICON_NAME+"に保存しました",-1
		noteadd "end",-1
		noteadd "--------------------------------------------",-1

		string=SAVE_ICON_NAME
	}

	if btnflag=2000{
		string=filename
	}

	//アイコンの表示
	if hicon:DestroyIcon hicon
	ExtractIconA hinstance,varptr(string),0
	hicon=stat
	color 200,200,200:boxf 0,0,120,300
	DrawIcon hdc,50,50,hicon
	redraw 1
*load_err
	//タイトルとmesboxの表示
	string=getpath(filename,8)
	title TITLENAME+" : "+string
	objprm 3,data
return


/////////////////////////////////////////////////////////////////
//アイコンの読込
*Load_Icon
	dialog "ico",16,""
	if stat!=1:return
	iconfile=refstr
	if hicon2:DestroyIcon hicon2
	ExtractIconA hinstance,varptr(iconfile),0
	hicon2=stat
	color 200,200,200:boxf 160,0,300,300
	dim tmp
	DrawIcon hdc,220,50,hicon2
	redraw 1
return

/////////////////////////////////////////////////////////////////
//アイコン書換
*change_icon
	exist filename
	if strsize=-1:dialog "実行ファイルが見つかりません":return
	bload filename,string,16,rsrc_data(5)+rsrc_data(4)
	if string!="DPMX0":dialog "HSP実行ファイルを指定して下さい":return
	exist iconfile
	tmp2=strsize
	if tmp2=-1:dialog "アイコンファイルが見つかりません":return
	//(RT_ICON)
	//tmpに一つのBMPデータサイズ取得
	bload iconfile,tmp,4,14
	if tmp>1000{
		dialog "アイコンサイズが大きすぎます"
		return
	}
	dialog filename+"を書き換えますか?",3,"危険"
	if stat=7 : return
	//(RT_ICON)
	//tmp2にBMPデータのオフセット取得
	bload iconfile,tmp2,4,18
	//BMPデータ読込
	bload iconfile,string,tmp,tmp2
	//EXEに保存
	bsave filename,string,tmp,icon_addr(2)
	//(RT_GROUP_ICON)
	//アイコンのヘッダ取得
	bload iconfile,string,22,0
	//イメージ1オフセット1サイズ等、書換
	wpoke string,0,0:wpoke string,2,1:wpoke string,4,1
	lpoke string,14,tmp : lpoke string,18,1
	//ヘッダ保存
	bsave filename,string,22,icon_addr(2)+tmp
	//IMAGE_RESOURCE_DATA_ENTRYの書換
	//(RT_ICON)サイズ
	bsave filename,tmp,4,icon_addr(0)+4
	//(RT_GROUP_ICON)オフセット
	tmp2=rsrc_data(3)+icon_addr(2)+tmp-rsrc_data(5)
	bsave filename,tmp2,4,icon_addr(1)
	btnflag=2000
	gosub *LoadFile2
return

/////////////////////////////////////////////////////////////////
//ソフト終了処理
*soft_end
	if hicon:DestroyIcon hicon
	if hicon2:DestroyIcon hicon2
end
コメント ( 0 ) | Trackback ( 0 )
« タブコントロ... PEフォーマッ... »
 
コメント
 
コメントはありません。
コメントを投稿する
 
名前
タイトル
URL
コメント
コメント利用規約に同意の上コメント投稿を行ってください。

数字4桁を入力し、投稿ボタンを押してください。