メインサイトへ戻る
;■■■PCゲーム改造初心者向け練習用プログラム No.1■■■
;正式名称:ののぴょん1号
;製作:うさぴょん
;協力:BlueAshさん 必殺!!猫まんま(はぐはぐ)さん
;バージョン:1.05
;*************************************************************************************************
;アセンブルに関する基本設定
;*************************************************************************************************
.386 ;アセンブルコードリストでは「;」以降がコメントとして無視される
.MODEL FLAT,STDCALL
locals ;この5行はTASMでアセンブルする場合に必要
jumps
UNICODE=0
;*************************************************************************************************
;データセクション(初期化)
;*************************************************************************************************
.DATA
WINTITLE db "PCゲーム解析練習用プログラム No1 (CDチェック編+α) 〜うさぴょん〜",0 ;ダイアログのタイトル
;WINTITLE db "ののぴょんは今日も元気! C#になんか負けないもん!",0 ;ダイアログのタイトル(予備)
POINT db "■■■ゲームの解析にあたり、先ず理解しておいて頂きたいポイント■■■",13,10
db 13,10
db "・アセンブリ言語を用いたプログラミングの基礎",13,10
db "・レジスタ、オペランド、ニーモニック、ポインタ、変数(初期化・未初期化)、各種命令等",13,10
db "・アセンブリ言語の命令とWindowsAPIの関数・メッセージとの関連",13,10
db "・APIの関数呼び出し時のパラメータ設定と返り値の扱い方",13,10
db "・PEファイルヘッダで設定された各セクションの役割",13,10
db "・ディスクイメージ上とメモリイメージ上での実行ファイルの違い",13,10
db "・ファイル名とファイルハンドルの違い、検索ハンドル、ウィンドウハンドル",13,10
db "・メニュー、ダイアログボックス、サブルーチン、構造体の定義とその仕組み",13,10
db "・ダイアログボックスとメッセージボックスの違い",13,10
db "・CDチェックやキー入力判断の動作原理と関連する関数",13,10
db "・ファイル入出力の基本と関連関数の使い方(ゲーム改造ツール作成の初歩)",13,10
db 13,10
db "<以下は理解しておいた方が望ましいこと>",13,10
;db "・ダイアログボックスのコントロールに入力された数字列と文字列の扱い方",13,10
db "・CD−DAデバイスのオープンとCD再生、MCI関連関数の使い方",0
;■■CDチェック関連■■
first db 'これからゲームCDの認証を行います',0 ;「,0」は文字列の終わりを示す
drive db '%c:\',0 ;ドライブパス作成様式
ask db ' このCD−ROMドライブでよろしいですか?',0
notice db ' ご注意',0
NoCD db 'CD−ROMドライブが見つかりません。',13,10 ;文字列を改行させています
db '「キャンセル」で終了します。',0
VolumeName db 'USAPYON',0 ;ゲームCDのボリュームラベル
IDfile db 'usapyon.dat',0 ;CD認証用ファイル名
file db '%s%s',0 ;CD認証用ファイルのパス作成様式
information db ' お知らせ',0
NoVolume db 'CDが挿入されていません。',13,10
db '次のCDドライブを探索します。',0
VolumeWrong db '別のCDが挿入されています。',13,10
db '次のCDドライブを探索します。',0
IDwrong db 'CD認証用ファイルがありません。',13,10
db '次のCDドライブを探索します。',0
IDthrough db 'CD認証用ファイルがありました。',0
SizeGood db 'ゲームCDが認証されました。',13,10
db '',13,10
db '「OK」でCD再生を停止し、終了します。',0
SizeWrong db 'このCD認証用ファイルは、',13,10
db '正規のものではありません。',13,10
db '次のCDドライブを探索します。',0
ReadOnly db 'CD認証用ファイルは、',13,10
db '読み取り専用属性です',13,10
db '次のCDドライブを探索します。',0
;■■CDチェックMCI処理関連■■
DeviceName db 'cdaudio',0
DeviceErr db 'ゲームCDが認証されましたが、cdaudioデバイスがオープンできません。',13,10
db '他のアプリケーションがデバイスを使用している可能性があります。',13,10
db '或いはBGMにMIDIが選択されました。',13,10
db '',13,10
db 'そのため、CD-DAの代わりに"usapyon.mid"を再生します。',13,10
db '',13,10
db '「OK」でMIDI再生を停止し、CDチェックを終了します。',0
WavPlay db '効果音ファイル("usapyon.wav")のみ再生します。',0
SetTrack db 'set cdaudio time format tmsf',0 ;トラックベースの再生を指定
PlayCDaudio db 'play cdaudio from 2 to 3',0 ;再生トラックの指定
CDstatus db 'status cdaudio media present',0
MediaErr db 'ゲームCDは認証されましたが、',13,10
db 'ドライブにCDメディアが確認できません',13,10
db '',13,10
db ' 終了します',0
MediaSafe db 'true',0
SetMidi db 'open usapyon.mid alias usausa',0 ;このファイルのデバイス名を「usausa」に
;実際には再生対象ファイル名をwsprintf関数で組み込むことになります。
SetWAV db 'open usapyon.wav alias usausa',0 ;WAVファイル再生用ストリングの例
PlayMidi db 'play usausa',0
StopMidi db 'stop usausa',0
CloseMidi db 'close usausa',0
CloseAll db 'close all',0
;■■ダイアログボックスプロシージャ関連■■
NOTDrive db 'エデットボックスにドライブパスを入力して下さい',0
Drive_Unknown db 'ドライブタイプは、不明、リモートドライブ或いはRAMディスクです',0
Drive_NON db '指定のドライブは存在しません',0
Drive_Hard db '指定ドライブのドライブタイプはハードディスクです',0
Drive_Fix db '指定ドライブのドライブタイプはリムーバブルディスクです',0
Drive_CD db '指定ドライブのドライブタイプはコンパクトディスク(CD)です',0
DriveExample db 'C:\',0 ;ドライブパス入力例
INTExample db '99999999',0 ;符号付き整数値入力例
atoi db '入力された値は、16進数では %#X となります。',13,10
db 'この処理では、入力された文字列(数字)を内部で数値に変換して処理しています。',13,10
db 'アルファベットは無視されます。',0
atoi16 db '入力された値は、10進数では %d となります。',13,10
db 'この処理では、入力された文字列(数字)を内部で数値に変換して処理しています。',0
Menuname db 'USAMENU',0
IconName db 'USA_ICON',0
;About db 'バージョン情報について',0 ;メッセージボックス用
AboutNotice db 'PCゲーム改造初心者向け練習用プログラム No.1 Ver1.05',13,10
db '正式名称 ののぴょん1号',13,10
db '製作 うさぴょん',13,10
db '',13,10
db '詳細なバージョン情報等は、この実行ファイルのプロパティを参照して下さい。',0
Dummy db '',0
CRCFormat db 'このファイルのCRC32は%08Xです。ファイルサイズは%uバイトです。',0
OpenMessage db 'open cdaudio',0
TrackMessage db 'play cdaudio from %u notify',0 ;MM_MCINOTIFYメッセージを返させる
StopCD db 'stop cdaudio',0
CloseCD db 'close cdaudio wait',0
EjectCD db 'set cdaudio door open',0
InsertCD db 'set cdaudio door closed',0
CDTrackExample db '2',0
URL_1 db 'http://gamereverserz.cjb.net/',0
URL_2 db 'http://scripterz.usaweb.nu/',0
URL_3 db 'http://msdn.microsoft.com/default.asp',0
URL_4 db 'http://www.microsoft.com/japan/developer/default.asp',0
INIPath db '\Usapyon.usa',0
DefSection db 'default',0
DefKey db 'TextFileEditor',0
DefKeyM1 db 'Mediafile1',0
DefKeyM2 db 'Mediafile2',0
DefKeyM3 db 'Mediafile3',0
DefKeyM4 db 'Mediafile4',0
DefKeyM5 db 'Mediafile5',0
DefKeyM6 db 'Mediafile6',0
DefKeyM7 db 'Mediafile7',0
DefKey3 db 'HexEditor',0
DefKey4 db 'Calculater',0
DefKey5 db 'Appli1',0 ;対象多数ならばwsprintf関数を使用
DefKey6 db 'Appli2',0
DefKey7 db 'Appli3',0
DefKey8 db 'Appli4',0
DefKey9 db 'Appli5',0
DefKey10 db 'Appli6',0
DefKey11 db 'Appli7',0
AVIPlayMessage db 'play %s ',0 ;ファイルパス指定だと"notify"設定不可
AVIResumeMessage db 'resume %s',0
AVIPauseMessage db 'pause %s',0
AVIStopMessage db 'stop %s',0
AVICloseMessage db 'close %s',0
SndVol db '%s\SNDVOL32.EXE',0 ;C:\WINDOWSとは限らない
;■■改造処理関連■■
Notepad db '%s\NOTEPAD.EXE',0 ;C:\WINDOWSとは限らない
SaveDataPos db 'SaveData',0
SaveWrong db 'ファイルハンドル取得処理中にエラーが発生しました。',13,10
db '他のアプリケーションが対象ファイルを使用している可能性があります。',0
MemWrong db 'メモリブロック確保処理中にエラーが発生しました',0
SerialWrong db '連続書き換え型コードで指定された値のバイト数と、同書き換え範囲の',13,10
db 'バイト数に不整合がみられます。安全と推定される範囲内で書き替えます。',0
ReplacePosInfo db '置換型コードにより、オフセット %#X 以降を書き替えます。',0
SearchWrong db '置換型コードで指定したバイナリデータのファイル内探索を完了しました。',0
SearchWrong2 db '置換型コードで指定したバイナリデータと、書き換え用データの',13,10
db 'サイズが異なります。書き替えを実行しますか?',0
WriteError db 'ファイルへの書き込みに失敗しました。',0
WriteError2 db 'ファイルへの書き込みに失敗しました。「キャンセル」で次のコードに移ります。',0
CharaZero db '置換対象或いは書き換え内容が0文字になっています。',13,10
db 'コード内に不必要な文字列が挿入されている可能性もあります。',0
NGCode db 'コードの様式に誤りがあります。',0
HexIntFormat db 'Offset:%#X [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X]',0
HexASCIIFormat db 'Offset:%#X 「%s」 (値00:文字列終端)',0
NOkey db 'NoKey',0
NOkey2 db '未選択',0
NOMenuOfSelectGame db '選択・改造されたゲームが特定できません。',0
askupdate db '選択中ゲーム及びエディットボックス内容の再確認を強くお奨めします',0
CheatInfoUpdate db '現在のエディットボックスの内容で選択中ゲームの「GAME*」セクションを更新します',13,10
db '本当に更新してもよろしいですか?',0
GameCount db 'GameCount',0
GameCodeCount db 'CodeCount',0
GameNameKey db 'GameName',0
GameSiteKey db 'URL',0
GameSectionFormat db 'GAME%u',0
SelectGameIs db '現在選択・改造中のゲームは %s です。',0
CodeNameFormat db 'Code%u',0
CheatDone db '改造処理を終了しました。',13,10
db '',13,10
db '',0
BackupName db '%s.BAK',0
BackupRewrite db 'バックアップファイルが既に存在します。上書きしますか?',0
TargetSection db 'TargetGame',0
TargetGameFormat db '改造対象%u',0
FUIList db '16進−2進ビットパターン:',13,10
db '00h=0000 01h=0001 02h=0010 03h=0011 04h=0100 05h=0101 06h=0110 07h=0111',13,10
db '08h=1000 09h=1001 0Ah=1010 0Bh=1011 0Ch=1100 0Dh=1101 0Eh=1110 0Fh=1111',13,10
db '',13,10
db '10進−16進(リトルエンディアン):',13,10
db '99=63h 999=E703h 9999=0F27h 99999=9F8601h 999999=3F420Fh 9999999=7F9698h',13,10
db '99999999=FFE0F505h 255=FF000000h 65535=FFFF0000h 16777215=FFFFFFFFh ',13,10
db '-100=9CFFFFFFh -1000=18FCFFFFh -10000=F0D8FFFFh ',13,10
db '',13,10
db 'その他',13,10
db '"Debug"=4465627567h "DEBUG"=4445425547h "Test"=54657374h "TEST"=54455354h',13,10
db '"警告"=8C788D90h "Error"=4572726F72h ',0
;■■その他■■
Usatut1mutex db 'UsaTut1x',0
TrayText db 'ののぴょん1号 [PCゲーム解析練習用プログラム No1 (CDチェック編)]',0
TheEnd db '終了(&E)',0
ToTopTrack db '最前面表示をトグル(&T)',0
;■■APIの関数呼び出し時の各パラメータを対応する値で設定■■
;パラメータ名は、WindowsAPIに準拠しています
;MessageBoxA関数用
mb_ok equ 30h ;「OK」ボタン(0h)+アイコン付き(30h)のメッセージボックス
mb_retrycancel equ 5 ;「再試行」「キャンセル」ボタンのあるメッセージボックス
;hWnd equ 0 ;親ウィンドウハンドルが不要ならば0です
mb_yesno equ 4 ;「はい」「いいえ」のボタンがあるメッセージボックス
mb_okcancel equ 1 ;「はい」「キャンセル」のボタンがあるメッセージボックス
idretry equ 4 ;「再試行」ボタンを押した場合の返り値
idno equ 7 ;「いいえ」ボタンを押した場合の返り値
idcancel equ 2 ;「キャンセル」ボタンを押した場合の返り値
;GetVolumeInformationA関数用
dwcVolumeNameSize equ 100h ;取得されたボリュームラベルの格納バッファバイト数
lpVolumeSerialNumber equ 0 ;ポインタだがボリュームシリアル番号が不要なら0でも可
lpFileSystemNameBuffer equ 0 ;ポインタだがファイルシステム名が不要なら0でも可
nFileSystemNameSize equ 0 ;ファイルシステム情報関連のパラメータで今回は不要です
;CreateFileA関数用
generic_read equ 80000000h ;読み取りアクセス
generic_write equ 40000000h ;書き込みアクセス
file_share_read equ 1 ;複数の読み取りアクセスが実行可能
lpsecurity_attribute equ 0 ;ファイルのセキュリティ属性(無効)
open_existing equ 3 ;ファイルをオープン
file_attribute_normal equ 80h ;ファイル属性(属性なし)
handle equ 0 ;ファイル作成時の拡張属性(不要)
;GetAsyncKeyState関数用
vk_shift equ 10h ;シフトキーの仮想キーコード
vk_control equ 11h ;Ctrlキーの仮想キーコード
vk_Menu equ 12h ;Altキーの仮想キーコード
;mciSendCommandA関数用
wDeviceIDOPEN equ 0 ;デバイスのオープンには不要なので「wDeviceID」と区別
MCI_OPEN equ 803h
MCI_OPEN_TYPE equ 2000h
MCI_NOTIFY equ 1
MCI_WAIT equ 2
MCI_CLOSE equ 804h
MCI_STOP equ 808h
;mciSendStringA関数用
MM_MCINOTIFY equ 3B9h
;ReadFile,WriteFile関数用
lpOverlapped equ 0
;GlobalAlloc関数用
GMEM_FIXED equ 0 ;この指定で戻り値は確保メモリブロック先頭アドレスとなる
;GetLastError関数用
ERROR_ALREADY_EXISTS equ 0B7h
ERROR_FILE_EXISTS equ 50h
;GetMenu,GetMenuState,CheckMenuItem,RemoveMenu,EnableMenuItem関数用
MF_BYPOSITION equ 400h ;メニューの識別に項目の相対的位置を使用
MF_BYCOMMAND equ 0 ;メニューの識別にIDを使用
MF_ENABLED equ 0
MF_GRAYED equ 1
MF_SEPARATOR equ 800h
MFS_CHECKED equ 8h
MFS_UNCHECKED equ 0
;ShellExecuteA関数用
SW_SHOWNORMAL equ 1
SW_MAXIMIZE equ 3
;SetWindowPos関数用
SWP_NOSIZE equ 1
SWP_NOMOVE equ 2
HWND_TOPMOST equ -1 ;最前面の設定用
HWND_TOP equ 0
HWND_BOTTOM equ 1
TrueSize equ 270fh ;CD認証用ファイルのファイルサイズは9999バイト
;ダイアログプロシージャ用
NULL equ 0
WM_NULL equ 0 ;以下のウィンドウメッセージに注目して下さい
WM_CREATE equ 01h
WM_CLOSE equ 0010h
WM_DESTROY equ 0002h
WM_SETICON equ 0080h
WM_INITDIALOG equ 0110h
WM_COMMAND equ 0111h
WM_TASKTRAY equ 0506h
WM_LBUTTONDOWN equ 0201h
WM_RBUTTONDOWN equ 0204h
WM_DROPFILES equ 0233h
WM_UNDO equ 304h
WM_CLEAR equ 303h
WM_CUT equ 300h
WM_COPY equ 301h
WM_PASTE equ 302h
WM_SETTEXT equ 0Ch
WM_SETFONT equ 30h
WM_GETFONT equ 31h
WM_CTLCOLORDLG equ 136h
WM_CTLCOLORLISTBOX equ 134h
WM_CTLCOLOREDIT equ 133h
EM_REPLACESEL equ 0C2h
EM_LINESCROLLL equ 0B6h
EM_SETSEL equ 0B1h
LB_GETCURSEL equ 188h
LB_SETCURSEL equ 186h
LB_ADDSTRING equ 180h
LBN_SELCHANGE equ 1 ;ウィンドウメッセージここまで
ICON_SMALL equ 0
USA_ICON equ 65h
DLG_MAIN equ 67h
EDIT_TEXT_OUT equ 03E9h
EDIT_DRIVE equ 03EBh
EDIT_INT equ 03F2h
EDIT_CDTRACK equ 138Bh
EDIT_NOWSelected equ 0DAEh
LIST_GAME equ 0DB1h
BTN_CHECK equ 03EFh
BTN_EXIT equ 03F0h
BTN_GETDTYPE equ 03ECh
BTN_AtoI equ 03F1h
BTN_PlayTrack equ 1388h
BTN_Stop equ 1389h
BTN_Eject equ 138Ah
BTN_ChInfoUpdate equ 0DB2h
BTN_CheatNow equ 0DB0h
MenuCD equ 07D1h
MenuTop equ 07FDh
MenuEND equ 07D2h
MenuTEXTPoint equ 07D3h
MenuTEXTALL equ 0804h;Last#
MenuTEXTALLClear equ 07E1h
MenuTEXTClear equ 07D4h
MenuTEXTUndo equ 07E0h
MenuCut equ 07F5h
MenuCopy equ 07F6h
MenuPaste equ 07F7h
MenuChangeFont equ 07F3h
MenuUndoFont equ 07F4h
MenuMemo equ 07DEh
MenuHex equ 07E2h
MenuCal equ 07E3h
MenuAppli1 equ 07E6h
MenuAppli2 equ 07E7h
MenuAppli3 equ 07E8h
MenuAppli4 equ 0800h
MenuAppli5 equ 0801h
MenuAppli6 equ 0802h
MenuAppli7 equ 0803h
MenuChInfo equ 2710h
MenuChInfoUpdate equ 07FEh
MenuDefINI equ 07E9h
MenuGameINI equ 07DFh
MenuCheat equ 4E20h
MenuCheatSelected equ 07FAh
MenuSelectGame equ 07F8h
MenuSelectGame2 equ 07F9h
MenuINIOpen equ 07F1h
MenuFUI equ 07F2h
MenuAbout equ 07D5h
MenuCDPlay equ 07D8h
MenuCDStop equ 07D9h
MenuCDEject equ 07DAh
MenuCDInsert equ 07DBh
MenuMulti1 equ 7531h
MenuMulti2 equ 7532h
MenuMulti3 equ 7533h
MenuMulti4 equ 7534h
MenuMulti5 equ 7535h
MenuMulti6 equ 7536h
MenuMulti7 equ 7537h
MenuAVI2 equ 07E4h
MenuAVI3 equ 07E5h
MenuAVI4 equ 07FBh
MenuVolume equ 07F0h
MenuTrackEnd equ 9C42h
MenuTrackTop equ 9C41h
CheckMidi equ 0FA0h
CheckWav equ 0FA2h
CDCheckSkip equ 0FA1h
CheckBackUp equ 0DACh
CheckNoWarning equ 0DADh
CheckUseHexEditor equ 0DB3h
Radio10 equ 0BB9h
Radio16 equ 0BBAh
SiteGame equ 07FCh
Site1 equ 07D6h
Site2 equ 07D7h
Site3 equ 07DCh
Site4 equ 07DDh
INIBufferSize equ 7FFFh
TargetBufferSize equ 40h
StartAppliBufSize equ 104h
WinPathCount equ 105h
;*************************************************************************************************
;データセクション(未初期化)
;*************************************************************************************************
;未初期化変数の宣言
;FindFirstFileA関数用
;WIN32_FIND_DATA STRUC ;WIN32_FIND_DATA構造体の定義(今回は不要)
;連続した一群のデータとなる点に注意
dwFileAttributes dd ? ;ファイル属性
ftCreationTime dd ?
ftLastAccessTime dd ?
ftLastWriteTime dd ?
nFileSizeHigh dd ?
nFileSizeLow dd ? ;ファイルのバイトサイズの下位ワード
dwReserved0 dd ?
dwReserved1 dd ?
cFileName db 104h DUP(?) ;「db 104h DUP(?)」でこの変数に260バイト確保しています
cAlternateFileName db 20h DUP(?) ;本来の14hだとバイト確保に不具合が起きます
;WIN32_FIND_DATA ENDS
;mciSendCommandA関数用
;MCI_OPEN_PARMS STRUC ;MCI_OPEN_PARMS構造体の定義(定義の必要が無い)
dwCallback dd ? ;実際にはNULLになる
wDeviceID dd ? ;デバイスID
lpstrDeviceType dd ? ;ここにデバイス名(cdaudio)が入る
lpstrElementName dd ?
lpstrAlias dd ?
;MCI_OPEN_PARMS ENDS
;Shell_NotifyIconA関数用
;NOTIFYICONDATA STRUC
iconDatacbSize dd ?
iconDatahWnd dd ?
iconDatauID dd ?
iconDatauFlags dd ?
iconDatauCallbackMessage dd ?
iconDatahIcon dd ?
iconDataszTip db 64h DUP(?)
;NOTIFYICONDATA ENDS
;GetCursorPos関数用
;POINT STRUC
CursorX dd ?
CursorY dd ?
;POINT ENDS
;以下の変数のサイズはddでも実際の処理上問題ありません
DrivePath dd ? ;CDドライブのパス
FindFileHandle dd ? ;CD認証用ファイルの検索ハンドル
FileHandle dd ? ;CD認証用ファイルのファイルハンドル
;GetVolumeInformationA関数用
lpMaximumComponentLength dd ? ;ファイルシステム情報関連のパラメータで今回は不要です
;ポインタなので値0ではなく未初期化変数にしています
;この変数を値0に定義するとPass32でエラーがでます
lpFileSystemFlags dd ? ;同上
lpVolumeNameBuffer db 104h DUP(?) ;取得されたボリュームラベルが格納されるポインタ
;CreateFileA関数用
FilePath db 104h DUP(?) ;同ファイルパス
;mciSendStringA関数用
MediaPresent db 20h DUP(?) ;後で再定義される
;ReadFile,WriteFile関数用
lpNumberOfBytesRead dd ? ;実際には使用しない
lpNumberOfBytesWritten dd ? ;同上
;GetFileTime,SetFileTime関数用(FileTime構造体を連続使用)
LowDateTime1 dd ?
HighDatetime1 dd ?
LowDateTime2 dd ?
HighDatetime2 dd ?
LowDateTime3 dd ?
HighDatetime3 dd ?
;ダイアログボックスプロシージャ用 他
hEdit dd ?
hicon dd ?
hinst_ dd ?
hDC dd ?
hDrop dd ?
hBrushDLG dd ?
hBrush dd ?
hBrush2 dd ?
hHeap dd ?
MenuHandle dd ?
SubMenuHandle dd ?
SubMenuHandle1 dd ?
SubMenuHandle2 dd ?
SUbCheckBuf db 120h DUP(?)
SUbCheckBuf2 db 20h DUP(?)
SUbCheckBuf3 db 90h DUP(?)
MCIMessBuf db 20h DUP(?)
DummyStrage db 150h DUP(?)
INIBuffer dd ? ;INIBufferSizeで再定義される
GameSectionNum dd ?
GameNum dd ?
GameNumID dd ?
GameTargetNum db 16h DUP(?)
SelectGameBuf db 70h DUP(?)
DirBuffer db 104h DUP(?) ;INIファイルパス格納先
DirBuffer2 db 104h DUP(?)
KeyReturn dd ?
CodeCountBuf dd ?
;CodeCountBuf2 dd ? ;予備
CodeNum dd ?
CodeName db 10h DUP(?)
CodeStart db 16h DUP(?)
CodeEnd db 16h DUP(?)
CodeFill db 200h DUP(?)
CodeFillBuf dd ?
CodeCountBuf2 dd ?
ReplaceData db 200h DUP(?)
ReplaceData2 db 100h DUP(?)
ReplaceFill db 200h DUP(?)
ReplaceFill2 db 100h DUP(?) ;書き替え時に必要なデータ
ReplacePos dd ?
ReplacePosString db 70h DUP(?)
CharaFlag dd ? ;同上
CharaFlag2 dd ?
SerialMacro dd ? ;同上
CodeStart2 db 8h DUP(?) ;同上
CodeEnd2 db 8h DUP(?) ;同上
CodeFill2 db 100h DUP(?) ;同上
PathBuffer db 104h DUP(?) ;同上
PathBuffer2 db 104h DUP(?) ;同上
FileSize dd ?
MemPtr dd ?
TargetBuffer db 40h DUP(?) ;TargetBufferSizeで再定義される
StartAppliBuf db 104h DUP(?) ;StartAppliBufSizeで再定義される
CodeErrorMess dd ?
FontHandle dd ?
WinPath db 105h DUP(?) ;WinPathCountで再定義される
WinAppliPath db 105h DUP(?)
DragFileBuf db 104h DUP(?)
XORBuf dd ?
GameCountBuf3 dd ?
CRC32TextBuf db 30h DUP(?)
CRC32Table db 400h DUP(?)
HexViewBuf db 60h DUP(?)
HexViewBuf2 db 60h DUP(?)
HexViewStringBuf db 12h DUP(?)
;*************************************************************************************************
;コードセクション(関数インポートセクション部)
;*************************************************************************************************
.CODE
extrn ExitProcess : proc ;「proc」はサブルーチンを定義する擬似命令
extrn MessageBoxA : proc ;メッセージボックスの作成
extrn CreateFileA : proc ;今回はファイルをオープンしています
extrn GetDriveTypeA : proc ;ドライブの種類を取得
extrn GetVolumeInformationA : proc ;ボリュームラベルの取得はこの関数以外でも可能です
extrn FindFirstFileA : proc ;指定の検索ファイル名と名前が一致する最初のファイルを検索
extrn FindClose : proc ;検索ハンドルを閉じる
extrn lstrcmpA : proc ;文字列を比較します
extrn CloseHandle : proc ;オープンしたファイルを閉じる
extrn GetFileSize : proc
extrn GetAsyncKeyState : proc ;特定のキーが押されたか調べる
extrn MessageBeep : proc
extrn mciSendCommandA : proc ;特定のMCIデバイスにコマンドを送る
extrn mciSendStringA : proc ;MCIデバイスにコマンドストリングを送る
extrn _wsprintfA : proc ;TASMではこの関数名の前に「_」が必要になる
;指定のフォーマット様式で文字列をフォーマットして出力
extrn GetModuleHandleA : proc ;特定のモジュールのハンドルを得る
extrn WritePrivateProfileStringA : proc ;INIファイルの指定セクションの特定キーに
;文字列値を書き込み
extrn DragAcceptFiles : proc ;ドラッグ・アンド・ドロップの許可
extrn DragQueryFile : proc ;ドラッグ・アンド・ドロップされたファイルの情報を取得
extrn DragFinish : proc ;同ファイル名転送用のメモリを開放
extrn LoadIconA : proc ;リソースからアイコンをロード
extrn DialogBoxParamA : proc ;ダイアログ作成用関数
extrn EndDialog : proc ;モーダルダイアログボックスを破棄
extrn SetWindowTextA : proc ;ウィンドウタイトルを設定
extrn SetDlgItemTextA : proc ;コントロールのタイトルかテキストを設定
extrn SendMessageA : proc ;メッセージを別ウィンドウに送って応答を待つ
extrn IsDlgButtonChecked : proc ;チェックボックスの選択状態を取得
extrn GetDlgItemTextA : proc ;ダイアログボックス内コントロール関連のタイトル
;またはテキストを取得
extrn LoadMenuA : proc ;リソースで定義されたメニューのハンドルを取得
extrn InsertMenuA : proc ;指定メニューの任意の位置にメニュー項目を追加
extrn SetMenu : proc ;メニューをウィンドウに接続
extrn GetMenu : proc ;ウィンドウハンドルからメニューハンドルを取得
extrn GetMenuState : proc ;ポップアップメニュー内メニュー項目の状態等を取得
extrn CheckMenuItem : proc ;メニュー項目にチェックを付ける(外す)
extrn GetDlgItemInt : proc ;ダイアログボックス内のコントロールから10進数列を
;取得し整数値に変換
extrn CheckRadioButton : proc ;ラジオボタングループの選択項目変更
extrn Sleep : proc ;プロセスを指定したミリ秒数だけ停止
extrn ShellExecuteA : proc ;指定したファイル等へ、指定した操作を実行する
extrn GetPrivateProfileStringA : proc ;プライベートINIファイルの特定キーの文字列を取得
extrn GetCurrentDirectoryA : proc ;プロセスのカレントフォルダを取得
extrn lstrcatA : proc ;文字列連結
extrn lstrcpyA : proc
extrn GetPrivateProfileSectionA : proc ;プライベートINIファイルの特定セクションの
;総てのキーと値を取得
extrn GetPrivateProfileIntA : proc ;プライベートINIファイルの特定キーの整数値を取得
extrn GetDlgItem : proc ;コントロールIDからダイアログボックスコントロール
;のウィンドウハンドルを取得
extrn CheckDlgButton : proc ;ボタンコントロールのチェックを付加または削除
extrn lstrlenA : proc ;文字列の長さを取得
extrn CreateMutexA : proc ;プロセスの同期を取るためのミューテックスオブジェクトを作成
extrn GetLastError : proc ;スレッドのローカル格納領域に設定された直前のエラーを取得
extrn GlobalAlloc : proc ;ヒープからメモリブロックを確保する
extrn GlobalFree : proc ;メモリブロックを開放する
extrn SetFilePointer : proc ;オープンファイルのファイルポインタを移動する
extrn ReadFile : proc ;ファイルからデータを読みこむ
extrn WriteFile : proc ;データをファイルを書きこむ
extrn SetFileAttributesA : proc ;ファイルの属性を設定
extrn CopyFileA : proc
extrn ModifyMenuA : proc ;メニュー項目のプロパティを変更する
extrn SendDlgItemMessageA : proc ;ダイアログボックスコントロールへメッセージを送る
extrn GetWindowsDirectoryA : proc ;ウィンドウフォルダのパスを取得
extrn Shell_NotifyIconA : proc ;タスクトレイにアイコンを追加
extrn TrackPopupMenu : proc ;画面の任意の位置にサブメニューを表示
extrn GetSubMenu : proc ;ポップアップメニューのハンドルを取得
extrn PostMessageA : proc ;メッセージキューにメッセージを入れて待たずに復帰
extrn GetCursorPos : proc
extrn DestroyMenu : proc ;メモリからメニューを削除
extrn AppendMenuA : proc ;メニューの最後に新しい項目を追加
extrn CreatePopupMenu : proc ;空のポップアップメニューを作成
extrn GetSystemMenu : proc ;システムメニューのハンドルを取得
extrn RemoveMenu : proc ;メニューからメニュー項目を削除
extrn SetForegroundWindow : proc ;ウィンドウをフォアグラウンドに移行し入力フォーカスを得る
extrn GetShortPathNameA : proc ;長いパス名を短いパス名に変換
extrn CreateSolidBrush : proc ;指定色のソリッド論理ブラシを作成
extrn DeleteObject : proc ;作成した論理GDIオブジェクトを削除
extrn GetFileTime : proc ;ファイルの作成日時・最終更新日時等を取得
extrn SetFileTime : proc ;ファイルの作成日時・最終更新日時等を設定
extrn SetWindowPos : proc ;ウィンドウ(子、ポップアップ、トップレベル)の
;サイズ、位置及び順序を変更
extrn GetProcessHeap : proc ;プロセスのデフォルトヒープのハンドルを得る
extrn HeapAlloc : proc ;ヒープからメモリブロックを確保する
extrn HeapFree : proc ;ヒープからメモリブロックを開放する
extrn WritePrivateProfileSectionA : proc ;プライベートINIファイルの特定のセクションの
;総てのキーと値を書き換え
extrn EnableWindow : proc ;ウィンドウを有効または無効にする
extrn EnableMenuItem : proc ;メニュー項目を有効または無効(淡色表示)にする
;extrn IsDebuggerPresent : proc ;Win98で実装された関数
;*************************************************************************************************
;コードセクション(コード本体)
;*************************************************************************************************
Start:
push NULL ;NULL設定にすればハンドルが戻り値
call GetModuleHandleA
test eax, eax
jne GoodModule
NotStart:
push 0
call ExitProcess
GoodModule:
mov hinst_, eax ;インスタンスハンドルをストア
push offset Usatut1mutex ;二重起動を回避
push 1 ;TRUE
push NULL
call CreateMutexA
call GetLastError
cmp eax, ERROR_ALREADY_EXISTS
je NotStart
;改造対策例(注:デバッガで対処可能)
;mov eax, offset IsDebuggerPresent + 1 ;関数呼び出し偽装(この関数はWin95不可)
;dec eax
;call eax ;対処法はDisTamper PROC参照
;test eax,eax ;デバッガから起動されている
;jnz NotStart
mov esi,offset DummyStrage ;他の関数で使用する変数を流用
mov dword ptr [esi], 5C2E5C5Ch ;.dataセクション文字列検索不可
mov dword ptr [esi+4],45434953h ;"\\.\SICE"(VxD,パス解析オフ)
call DisTamper ;解析ツール検出用サブルーチン
;dec eax
;je NotStart ;終了処理へ向かわせる例
mov dword ptr [esi+4],53584244h ;"\\.\DBXSTAND"
mov dword ptr [esi+8],444E4154h ;BlueAshさんのCDチェックに関する
call DisTamper ;チュートリアルを参考にしています
;dec eax
;je NotStart
mov dword ptr [esi+4],54535845h ;"\\.\EXSTAND"
mov dword ptr [esi+8],00444E41h ;同上
call DisTamper
;dec eax
;je NotStart
and dword ptr [esi], 0
and dword ptr [esi+4],0
and dword ptr [esi+8],0
;mov dword ptr [hBrushDLG],0 ;不要。GoodModule2参照
jmp GoodModule2
DisTamper PROC ;普通はルーチン呼び出し箇所と離します
mov eax,offset CreateFileA + 1234h ;関数呼び出しを偽装(逆アセンブラ対策)
mov hBrushDLG, eax ;他の関数で使用する変数を流用
xor eax,eax
push eax;handle
push file_attribute_normal
push open_existing
push eax;lpsecurity_attribute
inc eax
push eax;file_share_read
push generic_read + generic_write
push esi
sub dword ptr [hBrushDLG],1234h
Call dword ptr [hBrushDLG] ;OllyDbgならインポートセクション内の
;関数対応アドレスにBPM(R)設定で、
;本家なら「bpx createfilea」でブレーク
inc eax ;0FFFFFFFFh:起動されていない
je AllClear ;通常処理へ
dec eax ;「cmp eax,0FFFFFFFFh」は使用しない
push eax ;解析の端緒になりかねないので、故意に
call CloseHandle ;クローズしないケースもあります
push mb_ok
call MessageBeep ;警告音を鳴らします
mov eax, 1 ;解析ツール検出フラグON
AllClear:
ret
DisTamper ENDP
GoodModule2:
push 0C0C0C0h
call CreateSolidBrush
mov hBrushDLG, eax
push 0F5FFF5h
call CreateSolidBrush
mov hBrush, eax
push 0FFFFF4h
call CreateSolidBrush
mov hBrush2, eax
push offset Menuname
push hinst_
call LoadMenuA
mov dword ptr [offset MenuHandle],eax
push offset DirBuffer ;■■■以下でゲーム改造関連メニュー作成・追加■■■
push 104h ;上バッファのサイズ
call GetCurrentDirectoryA
push 104h ;ここではパス名のなので104hに再定義
push offset DirBuffer
push offset DirBuffer
call GetShortPathNameA
push offset INIPath
push offset DirBuffer
call lstrcatA ;INIファイル(usapyon.usa)のパスを作成しておく
push offset DirBuffer
push 0
push offset GameCount
push offset TargetSection
call GetPrivateProfileIntA
mov dword ptr [GameNum], eax
mov ebx, 0
mov dword ptr [GameNumID], MenuChInfo
AddMenu:
inc ebx
push ebx
push offset TargetGameFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
push offset GameTargetNum
push dword ptr [GameNumID] ;新しく作成するメニューの識別子
push 0
push 2098 ;MenuID=2098の上に新メニューを作成
push MenuHandle
call InsertMenuA
push offset GameTargetNum
add dword ptr [GameNumID],10000
push dword ptr [GameNumID] ;新しく作成するメニューの識別子
push 0
push 2097 ;MenuID=2097の上に新メニューを作成
push MenuHandle
call InsertMenuA
sub dword ptr [GameNumID],10000
mov edi, offset GameTargetNum ;「改造対象#」で設定したゲーム名をメニュー項目名に設定
mov esi, dword ptr [GameNumID]
call GAMEMenu
add dword ptr [GameNumID],1
cmp ebx,dword ptr [GameNum]
jb AddMenu ;GameCount=Maxまでループ
call GetProcessHeap ;INIBuffer用メモリブロック確保
mov hHeap, eax
push 7FFFh
push 8h
push hHeap
call HeapAlloc
mov INIBuffer, eax
push 0 ;WM_INITDIALOG処理関連パラメータだが今回は不要
push offset DlgProcedure ;ダイアログボックスプロシージャを指定
push 0 ;親ウィンドウのハンドルは不要
push DLG_MAIN ;ダイアログを指定
push hinst_ ;インスタンスハンドルを指定
call DialogBoxParamA
push 0
call ExitProcess
;*************************************************************************************************
;メインダイアログの定義
;*************************************************************************************************
PUBLIC DlgProcedure ;■■■ダイアログボックスプロシージャ設定■■■
DlgProcedure PROC STDCALL, hwnd_:DWORD, wmsg:DWORD, wparam_:DWORD, lparam_:DWORD
USES ebx, edi, esi
xor eax, eax
mov ax, word ptr [wmsg] ;■ウィンドウメッセージ判定■
cmp ax, WM_DESTROY ;ウィンドウメッセージ
je WMdestroy
cmp ax, WM_CLOSE ;ウィンドウメッセージ
je WMdestroy
cmp ax, WM_COMMAND ;ウィンドウメッセージ
je WMcommand
cmp ax, WM_INITDIALOG ;ウィンドウメッセージ
je InitDlg
cmp ax, WM_DROPFILES ;ウィンドウメッセージ
je WMdropfiles
cmp ax, MM_MCINOTIFY ;マルチメディアメッセージ
je CD_Stop ;「Stop」ボタン押下ではなくCDトラック再生終了を検出するため
cmp ax, WM_TASKTRAY ;ウィンドウメッセージ
je WMTasktray
cmp ax, WM_CTLCOLORDLG ;ウィンドウメッセージ
je WMCtlcolordlg
cmp ax, WM_CTLCOLORLISTBOX ;ウィンドウメッセージ
je WMCtlcolorlistbox
cmp ax, WM_CTLCOLOREDIT ;ウィンドウメッセージ
je WMCtlcoloredit
xor eax, eax
RET
WMCtlcolordlg:
mov eax, hBrushDLG
mov dword ptr [wparam_], eax
ret
WMCtlcolorlistbox:
mov eax, hBrush
mov dword ptr [wparam_], eax
ret
WMCtlcoloredit:
mov eax, hBrush2
mov dword ptr [wparam_], eax
ret
WMTasktray: ;■■■システムトレイ設定■■■
push offset CursorX
call GetCursorPos
mov eax, dword ptr [lparam_]
cmp eax, WM_LBUTTONDOWN ;左クリック判定
jnz WMTasktray2
push 5
push MenuHandle
call GetSubMenu
mov SubMenuHandle, eax
push hwnd_
call SetForegroundWindow
push 0
push hwnd_
push 0
push CursorY ;以下でメニュー位置と様式を指定
push CursorX
push 28h ;TPM_LEFTBUTTON + TPM_RIGHTALIGN + TPM_BOTTOMALIGN
push SubMenuHandle
call TrackPopupMenu ;システムトレイ上にポップアップメニュー表示
;本来のメニューを接続しているので破棄できない
;ただし、メモリリークは起きない
push offset iconDatacbSize
push 3 ;NIM_SETFOCUS(要IE5だが、なくてもさして問題はない)
call Shell_NotifyIconA ;タスクトレイにフォーカスを戻す
push 0
push 0
push WM_NULL
push hwnd_
call PostMessageA
jmp WMTasktray3
WMTasktray2:
cmp eax, WM_RBUTTONDOWN ;右クリック判定
jnz WMTasktray3
call CreatePopupMenu
mov SubMenuHandle1, eax
push offset ToTopTrack
push MenuTrackTop
push 0
push SubMenuHandle1
call AppendMenuA
push offset Dummy
push 2099
push MF_SEPARATOR
push SubMenuHandle1
call AppendMenuA
push offset TheEnd
push MenuTrackEnd
push 0
push SubMenuHandle1
call AppendMenuA
push hwnd_
call SetForegroundWindow
push 0
push hwnd_
push 0
push CursorY ;以下でメニュー位置と様式を指定
push CursorX
push 2Ah ;TPM_RIGHTBUTTON + TPM_RIGHTALIGN + TPM_BOTTOMALIGN
push SubMenuHandle1
call TrackPopupMenu ;システムトレイ上にポップアップメニュー表示
push offset iconDatacbSize
push 3 ;NIM_SETFOCUS(要IE5)
call Shell_NotifyIconA ;タスクトレイにフォーカスを戻す
push SubMenuHandle1
call DestroyMenu ;独自作成メニューなので破棄しないとメモリを占有したままに
push 0
push 0
push WM_NULL
push hwnd_
call PostMessageA
WMTasktray3:
ret
WMdestroy: ;終了処理
call CD_END ;必ずCD再生を停止し、デバイスをクローズする
push 0
push 0
push 0
push offset CloseAll
call mciSendStringA ;必ずオープンした全マルチメディアのデバイスをクローズする
push offset iconDatacbSize
push 2 ;NIM_DELETE
call Shell_NotifyIconA ;タスクトレイのアイコンを破棄
push hBrush
call DeleteObject
push hBrush2
call DeleteObject
push hBrushDLG
call DeleteObject
push INIBuffer
push 40h
push hHeap
call HeapFree
push 0
push hwnd_
call EndDialog
push 0
call ExitProcess
WMcommand: ;■■■ダイアログの通常処理■■■
mov eax, dword ptr [wparam_] ;■ダイアログ上の処理判定■
cmp ax, LIST_GAME
je ListSelect
cmp eax, BTN_CHECK ;「CDチェック」ボタンが押されたか判定
je CheckMain
cmp eax, BTN_GETDTYPE
je CheckSub
cmp eax, BTN_EXIT
je WMdestroy
cmp eax, BTN_AtoI
je AtoIConv
cmp eax, BTN_PlayTrack
je CD_Play
cmp eax, BTN_Stop
je CD_Stop
cmp eax, BTN_Eject
je CD_Eject
cmp eax, BTN_ChInfoUpdate
je GameSectionUpdate
cmp eax, BTN_CheatNow
je GameCheatFromBTN
cmp eax, MenuCD ;メニュー選択
je CheckMain
cmp eax, MenuTop
je FixTopWindow
cmp eax, MenuTrackTop
je FixTopWindow
cmp eax, MenuTrackEnd
je WMdestroy
cmp eax, MenuEND
je WMdestroy
cmp eax, MenuAbout
je AboutBox
cmp eax, MenuTEXTPoint
je TEXTpoint2
cmp eax, MenuTEXTClear
je EDIT_TEXT_OUT_Clear
cmp eax, MenuTEXTALL
je EDIT_TEXT_OUT_ALL
cmp eax, MenuTEXTALLClear
je EDIT_TEXT_OUT_ALLClear
cmp eax, MenuTEXTUndo
je EDIT_TEXT_OUT_UNDO
cmp eax, MenuCut
je EDIT_TEXT_OUT_Cut
cmp eax, MenuCopy
je EDIT_TEXT_OUT_Copy
cmp eax, MenuPaste
je EDIT_TEXT_OUT_Paste
cmp eax, MenuChangeFont
je ChangeFont
cmp eax, MenuUndoFont
je UndoFont
cmp eax, MenuCDPlay
je CD_Play
cmp eax, MenuCDStop
je CD_Stop
cmp eax, MenuCDEject
je CD_Eject
cmp eax, MenuCDInsert
je CD_Insert
cmp eax, MenuGameINI
je INIindicateGame
cmp eax, MenuFUI
je FUI
cmp eax, MenuSelectGame
je NowSelectGame
cmp eax, MenuSelectGame2
je NowSelectGame
cmp eax, MenuChInfoUpdate
je GameSectionUpdate
cmp eax, MenuCheatSelected
je CheatSelectedGame
cmp eax, MenuCheat
jae GameCheatPre
jmp WParamContinue
GameCheatPre:
cmp eax, MenuCheat+100 ;とりあえず100ゲームまで対応
ja WParamContinue
jmp GameCheat
WParamContinue:
cmp eax, MenuChInfo
jae INIindicatePre
jmp WParamContinue2
INIindicatePre:
cmp eax, MenuChInfo+100
ja WParamContinue2
jmp INIindicate
WParamContinue2:
cmp eax, MenuINIOpen
je INIOpen
cmp eax, Site1
je URL_DT
cmp eax, Site2
je URL_DT2
cmp eax, Site3
je URL_MSDN
cmp eax, Site4
je URL_MSDN2
cmp eax, SiteGame
je URL_GAME
cmp eax, MenuMemo
je MemoStart
cmp eax, MenuDefINI
je INIindicateDef
cmp eax, MenuMulti1
je AVIStart1
cmp eax, MenuMulti2
je AVIStart2
cmp eax, MenuMulti3
je AVIStart3
cmp eax, MenuMulti4
je AVIStart4
cmp eax, MenuMulti5
je AVIStart5
cmp eax, MenuMulti6
je AVIStart6
cmp eax, MenuMulti7
je AVIStart7
cmp eax, MenuAVI2
je AVIPause
cmp eax, MenuAVI3
je AVIStop
cmp eax, MenuAVI4
je AVIResume
cmp eax, MenuVolume
je SndVol32
cmp eax, MenuHex
je HexStart
cmp eax, MenuCal
je CalStart
cmp eax, MenuAppli1
je Appli1Start
cmp eax, MenuAppli2
je Appli2Start
cmp eax, MenuAppli3
je Appli3Start
cmp eax, MenuAppli4
je Appli4Start
cmp eax, MenuAppli5
je Appli5Start
cmp eax, MenuAppli6
je Appli6Start
cmp eax, MenuAppli7
je Appli7Start
RET
WMdropfiles: ;■■■ドラッグ・アンド・ドロップされたファイルの処理■■■
mov ebx, dword ptr [wparam_]
mov hDrop,ebx
push 104h
push offset DragFileBuf
push 0 ;一度に1つのファイルのみ受け付けるように制限(安全策)
push hDrop
call DragQueryFile
mov edi, offset GetAsyncKeyState
Push vk_control ;Ctrlキー
Call edi ;キーが押されたかチェックしてEAXレジスタに値を返す
cmp ah,80h ;キーが現在押されていればah=80h
jz WMdropfiles2 ;押されていれば指定したテキストファイルエディタで開く
Push vk_Menu ;Altキー
Call edi
cmp ah,80h
jz WMdropfiles3 ;押されていれば指定したヘキサエディタで開く
Push 41h ;Aキー
Call edi
cmp ah,80h
jz WMdropfiles4 ;押されていれば登録したアプリケーション1で開く
Push 5Ah ;Zキー
Call edi
cmp ah,80h
jz WMdropfiles5 ;押されていれば登録したアプリケーション2で開く
Push 58h ;Xキー
Call edi
cmp ah,80h
jz WMdropfiles6 ;押されていれば登録したアプリケーション3で開く
Push 53h ;Sキー 選択中ゲームのセーブデータのパスを変更
Call edi
cmp ah,80h
jz SaveDataNameCh
Push 54h ;Tキー 基本設定のテキストファイルエディタを変更
Call edi
cmp ah,80h
jz TextFileEditorCH
Push 48h ;Hキー 基本設定のヘキサエディタを変更
Call edi
cmp ah,80h
jz HexEditorCH
Push 51h ;Qキー 基本設定のアプリケーション1を変更
Call edi
cmp ah,80h
jz Appli1CH
Push 57h ;Wキー
Call edi
cmp ah,80h
jz Appli2CH
Push 45h ;Eキー
Call edi
cmp ah,80h
jz Appli3CH
Push 52h ;Rキー
Call edi
cmp ah,80h
jz Appli4CH
Push 47h ;Gキー
Call edi
cmp ah,80h
jz Appli5CH
Push 59h ;Yキー
Call edi
cmp ah,80h
jz Appli6CH
Push 55h ;Uキー
Call edi
cmp ah,80h
jz Appli7CH
Push 43h ;Cキー ドラッグ・アンド・ドロップされたファイルのCRCを取得
Call edi
cmp ah,80h
jz GetCRC
Push 31h ;1キー 基本設定のマルチメディアファイル1を変更
Call edi
cmp ah,80h
jz AVIFileCH1
Push 32h ;2キー
Call edi
cmp ah,80h
jz AVIFileCH2
Push 33h ;3キー
Call edi
cmp ah,80h
jz AVIFileCH3
Push 34h ;4キー
Call edi
cmp ah,80h
jz AVIFileCH4
Push 35h ;5キー
Call edi
cmp ah,80h
jz AVIFileCH5
Push 36h ;6キー
Call edi
cmp ah,80h
jz AVIFileCH6
Push 37h ;7キー
Call edi
cmp ah,80h
jz AVIFileCH7
Push 61h ;1キー(テンキー) 基本設定のマルチメディアファイルを変更
Call edi
cmp ah,80h
jz AVIFileCH1
Push 62h ;2キー
Call edi
cmp ah,80h
jz AVIFileCH2
Push 63h ;3キー
Call edi
cmp ah,80h
jz AVIFileCH3
Push 64h ;4キー
Call edi
cmp ah,80h
jz AVIFileCH4
Push 65h ;5キー
Call edi
cmp ah,80h
jz AVIFileCH5
Push 66h ;6キー
Call edi
cmp ah,80h
jz AVIFileCH6
Push 67h ;7キー
Call edi
cmp ah,80h
jz AVIFileCH7
jmp WMdropfilesMain2 ;簡易テキスト表示
WMdropfiles2:
mov esi,offset DefKey
jmp WMdropfilesMain
WMdropfiles3:
mov esi,offset DefKey3
jmp WMdropfilesMain
WMdropfiles4:
mov esi,offset DefKey5
jmp WMdropfilesMain
WMdropfiles5:
mov esi,offset DefKey6
jmp WMdropfilesMain
WMdropfiles6:
mov esi,offset DefKey7
WMdropfilesMain:
push 104h ;ここではパス名のなので104hに再定義
push offset DragFileBuf
push offset DragFileBuf
call GetShortPathNameA
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push esi
push offset DefSection
call GetPrivateProfileStringA
push 104h ;ここではパス名のなので104hに再定義
push INIBuffer
push INIBuffer
call GetShortPathNameA
push SW_SHOWNORMAL
push 0
push offset DragFileBuf
push INIBuffer
push 0
push hwnd_
call ShellExecuteA
push hDrop
call DragFinish ;ドラッグ・アンド・ドロップ処理終了
ret
WMdropfilesMain2:
push 104h ;ここではパス名のなので104hに再定義
push offset DragFileBuf
push offset DragFileBuf
call GetShortPathNameA
push handle
push file_attribute_normal
push open_existing
push lpsecurity_attribute
push file_share_read
push generic_read ; + generic_write
push offset DragFileBuf
Call CreateFileA
mov FileHandle,eax ;返り値のファイルハンドルを退避
push 0 ;ファイルサイズがFFFFFFFFhバイト以上の場合は必要
push FileHandle
Call GetFileSize
mov FileSize,eax
push FileSize
push GMEM_FIXED
Call GlobalAlloc
mov MemPtr,eax ;確保したメモリブロックのポインタを退避
cmp eax,0
jnz WMdropfilesMain3
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset MemWrong
push hwnd_
Call MessageBoxA
jmp WMdropfilesMain4
WMdropfilesMain3:
cmp FileSize, 7800h ;エディットコントロールへのテキスト表示サイズを限定
jb WMdropfilesMain3a ;SET_LIMITTEXTでも可
mov FileSize, 7800h
WMdropfilesMain3a:
push 0
push 0
push 0
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesRead
push FileSize
push MemPtr
push FileHandle
Call ReadFile
push MemPtr
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA ;他に良い方法がありますが、特に問題が無いのでこの関数を使用
push MemPtr
call GlobalFree
WMdropfilesMain4:
push FileHandle
call CloseHandle
push hDrop
call DragFinish ;ドラッグ・アンド・ドロップ処理終了
ret
GetCRC: ;■■■CRC取得処理■■■
push 104h ;ここではパス名のなので104hに再定義
push offset DragFileBuf
push offset DragFileBuf
call GetShortPathNameA
push handle
push file_attribute_normal
push open_existing
push lpsecurity_attribute
push file_share_read
push generic_read ; + generic_write
push offset DragFileBuf
Call CreateFileA
mov FileHandle,eax ;返り値のファイルハンドルを退避
push 0 ;ファイルサイズがFFFFFFFFhバイト以上の場合は必要
push FileHandle
Call GetFileSize
mov FileSize,eax
push FileSize
push GMEM_FIXED
Call GlobalAlloc
mov MemPtr,eax ;確保したメモリブロックのポインタを退避
cmp eax,0
jnz WMdropfilesMain3b
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset MemWrong
push hwnd_
Call MessageBoxA
jmp WMdropfilesMain4a
WMdropfilesMain3b:
push 0
push 0
push 0
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesRead
push FileSize
push MemPtr
push FileHandle
Call ReadFile
CRCTableMake1:
xor ecx,ecx
CRCTableMake2:
mov eax,ecx
xor edx,edx
CRCTableMake4:
test al,1
je CRCTableMake6
shr eax,1
xor eax,0EDB88320h ;Polynomial
jmp CRCTableMake7
CRCTableMake6:
shr eax,1
CRCTableMake7:
inc edx
cmp edx,8
jb CRCTableMake4
mov dword ptr [CRC32Table+4*ecx],eax
inc ecx
cmp ecx,255
jbe CRCTableMake2
mov edx,MemPtr
mov ecx,FileSize
or eax,-1 ;initial value = 0xFFFFFFFF
jmp CRC3
CRC2:
mov ebx,eax
xor bl,byte ptr [edx]
and ebx,255
mov ebx,dword ptr [CRC32Table+4*ebx]
shr eax,8
xor ebx,eax
mov eax,ebx
inc edx
CRC3:
dec ecx
jns CRC2
xor eax, 0FFFFFFFFh
push FileSize
push eax
push offset CRCFormat
push offset CRC32TextBuf
call _wsprintfA
add esp,10h
push offset CRC32TextBuf
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA
push MemPtr
call GlobalFree
WMdropfilesMain4a:
push FileHandle
call CloseHandle
push hDrop
call DragFinish ;ドラッグ・アンド・ドロップ処理終了
ret
SaveDataNameCh: ;書き換え対象セーブデータのパスを変更
mov esi, offset GameTargetNum
mov eax, offset SaveDataPos
jmp KeyValueChMain
TextFileEditorCH:
mov esi, offset DefSection
mov eax, offset DefKey
jmp KeyValueChMain
HexEditorCH:
mov esi, offset DefSection
mov eax, offset DefKey3
jmp KeyValueChMain
Appli1CH:
mov esi, offset DefSection
mov eax, offset DefKey5
jmp KeyValueChMain
Appli2CH:
mov esi, offset DefSection
mov eax, offset DefKey6
jmp KeyValueChMain
Appli3CH:
mov esi, offset DefSection
mov eax, offset DefKey7
jmp KeyValueChMain
Appli4CH:
mov esi, offset DefSection
mov eax, offset DefKey8
jmp KeyValueChMain
Appli5CH:
mov esi, offset DefSection
mov eax, offset DefKey9
jmp KeyValueChMain
Appli6CH:
mov esi, offset DefSection
mov eax, offset DefKey10
jmp KeyValueChMain
Appli7CH:
mov esi, offset DefSection
mov eax, offset DefKey11
jmp KeyValueChMain
AVIFileCH1:
mov esi, offset DefSection
mov eax, offset DefKeyM1
jmp KeyValueChMain
AVIFileCH2:
mov esi, offset DefSection
mov eax, offset DefKeyM2
jmp KeyValueChMain
AVIFileCH3:
mov esi, offset DefSection
mov eax, offset DefKeyM3
jmp KeyValueChMain
AVIFileCH4:
mov esi, offset DefSection
mov eax, offset DefKeyM4
jmp KeyValueChMain
AVIFileCH5:
mov esi, offset DefSection
mov eax, offset DefKeyM5
jmp KeyValueChMain
AVIFileCH6:
mov esi, offset DefSection
mov eax, offset DefKeyM6
jmp KeyValueChMain
AVIFileCH7:
mov esi, offset DefSection
mov eax, offset DefKeyM7
KeyValueChMain:
push offset DirBuffer
push offset DragFileBuf
push eax
push esi
call WritePrivateProfileStringA ;INIファイルに書き込み
push hDrop
call DragFinish ;ドラッグ・アンド・ドロップ処理終了
call MediaMenuChange
ret
InitDlg: ;■■■ダイアログの初期処理■■■
push 1
push hwnd_
call DragAcceptFiles ;ドラッグ・アンド・ドロップの許可
push offset IconName
push hinst_
call LoadIconA
test eax, eax
je TEXTpoint ;アイコンのロードに失敗
mov hicon, eax
push hicon
push ICON_SMALL
push WM_SETICON ;ウィンドウメッセージ
push hwnd_
call SendMessageA
mov dword ptr [offset iconDatacbSize],7Ch ;NOTIFYICONDATA構造体の設定
mov eax, hwnd_
mov dword ptr [offset iconDatahwnd],eax
mov dword ptr [offset iconDatauID],1
mov dword ptr [offset iconDatauFlags],7 ;NIF_ICON +NIF_MESSAGE + NIF_TIP
mov dword ptr [offset iconDatauCallbackMessage],WM_TASKTRAY
mov eax, hicon
mov dword ptr [offset iconDatahIcon],eax
push offset TrayText
push offset iconDataszTip
call lstrcpyA
push offset iconDatacbSize
push 0 ;NIM_ADD
call Shell_NotifyIconA ;タスクトレイにアイコン追加
push 0
push hwnd_
call GetSystemMenu ;不要なシステムメニューを削除
mov SubMenuHandle2, eax
push MF_BYPOSITION
push 0 ;不要なシステムメニューの位置
push SubMenuHandle2
call RemoveMenu
push MF_BYPOSITION
push 1
push SubMenuHandle2
call RemoveMenu
push MF_BYPOSITION
push 2
push SubMenuHandle2
call RemoveMenu
TEXTpoint:
push EDIT_TEXT_OUT
push hwnd_
call GetDlgItem
mov dword ptr [offset hEdit],eax ;エディットコントロールのハンドルを取得・退避
push offset WINTITLE
push hwnd_
call SetWindowTextA ;ウィンドウタイトルを設定
test eax, eax
je WMdestroy
push offset DriveExample
push EDIT_DRIVE
push hwnd_
call SetDlgItemTextA ;ドライブ入力例を表示
push offset INTExample
push EDIT_INT
push hwnd_
call SetDlgItemTextA ;CDトラック番号入力例を表示
push offset CDTrackExample
push EDIT_CDTRACK
push hwnd_
call SetDlgItemTextA
push 0BB9h ;ラジオボタンの初期状態を設定
push 0BBAh
push 0BB9h
push hwnd_
call CheckRadioButton
push 1 ;チェックを付加
push CheckBackUp
push hwnd_
call CheckDlgButton ;チェックボタンの状態を設定
push 1
push CheckNoWarning
push hwnd_
call CheckDlgButton
push dword ptr [offset MenuHandle]
push hwnd_
call SetMenu
call MediaMenuChange
push 0
push 0
push WM_GETFONT
push hwnd_
call SendMessageA
mov dword ptr [FontHandle], eax
push WinPathCount
push offset WinPath
Call GetWindowsDirectoryA
mov ebx, 0
AddListBox:
inc ebx
push ebx
push offset TargetGameFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
mov edi, offset GameTargetNum
push offset DirBuffer
push TargetBufferSize
push offset TargetBuffer
push offset NOkey
push edi
push offset TargetSection
call GetPrivateProfileStringA
push offset TargetBuffer
push ebx
push LB_ADDSTRING
push LIST_GAME ;ListBoxのID
push hwnd_
call SendDlgItemMessageA ;「改造対象#」で設定したゲーム名をリスト項目名に設定
cmp ebx,dword ptr [GameNum]
jb AddListBox ;GameCount=登録数までループ
push BTN_ChInfoUpdate
push hwnd_
call GetDlgItem ;改造関連ボタンの無効化
push 0 ;FALSE
push eax
call EnableWindow
push BTN_CheatNow
push hwnd_
call GetDlgItem
push 0 ;FALSE
push eax
call EnableWindow
push MF_BYCOMMAND + MF_GRAYED
push MenuChInfoUpdate
push MenuHandle
call EnableMenuItem
push MF_BYCOMMAND + MF_GRAYED
push MenuCheatSelected
push MenuHandle
call EnableMenuItem
push MF_BYCOMMAND + MF_GRAYED
push SiteGame
push MenuHandle
call EnableMenuItem
push 0
push 8
push 0C5h;EM_LIMITTEXT
push EDIT_INT
push hwnd_
call SendDlgItemMessageA
TEXTpoint2:
push offset POINT
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA ;「今回のポイント」を表示
BacktoDLG: ;CDチェックルーチン他からここに戻る
RET ;戻ってからRET命令に繋ぐ方が簡単
MediaMenuChange PROC
mov edi, offset DefKey5 ;「Appli#」で設定したアプリパスをメニュー項目名に設定
mov esi, MenuAppli1
call StartAppliMenu
mov edi, offset DefKey6
mov esi, MenuAppli2
call StartAppliMenu
mov edi, offset DefKey7
mov esi, MenuAppli3
call StartAppliMenu
mov edi, offset DefKey8
mov esi, MenuAppli4
call StartAppliMenu
mov edi, offset DefKey9
mov esi, MenuAppli5
call StartAppliMenu
mov edi, offset DefKey10
mov esi, MenuAppli6
call StartAppliMenu
mov edi, offset DefKey11
mov esi, MenuAppli7
call StartAppliMenu
mov edi, offset DefKeyM1 ;「Mediafile#」で設定したファイルパスをメニュー項目名に設定
mov esi, MenuMulti1
call StartAppliMenu
mov edi, offset DefKeyM2
mov esi, MenuMulti2
call StartAppliMenu
mov edi, offset DefKeyM3
mov esi, MenuMulti3
call StartAppliMenu
mov edi, offset DefKeyM4
mov esi, MenuMulti4
call StartAppliMenu
mov edi, offset DefKeyM5
mov esi, MenuMulti5
call StartAppliMenu
mov edi, offset DefKeyM6
mov esi, MenuMulti6
call StartAppliMenu
mov edi, offset DefKeyM7
mov esi, MenuMulti7
call StartAppliMenu
ret
MediaMenuChange ENDP
GAMEMenu PROC
push offset DirBuffer
push TargetBufferSize
push offset TargetBuffer
push offset NOkey
push edi
push offset TargetSection
call GetPrivateProfileStringA ;”改造対象#”キー読み込み
push hwnd_
call GetMenu
push offset TargetBuffer
push esi ;「改造情報詳細」直下のメニュー項目
push 0
push esi
push MenuHandle
call ModifyMenuA ;メニュー項目をゲーム名に変更
add esi, 10000 ;メニューID参照
push hwnd_
call GetMenu
push offset TargetBuffer
push esi ;「改造直実行」直下のメニュー項目
push 0
push esi
push MenuHandle
call ModifyMenuA
ret
GAMEMenu ENDP
StartAppliMenu PROC
push offset DirBuffer
push StartAppliBufSize
push offset StartAppliBuf
push offset NOkey
push edi
push offset DefSection
call GetPrivateProfileStringA ;”Appli#”キー読み込み
push hwnd_
call GetMenu
push offset StartAppliBuf
push esi ;「指定アプリの起動」直下のメニュー項目
push 0
push esi
push eax
call ModifyMenuA ;メニュー項目をパスに変更
ret
StartAppliMenu ENDP
MenuOfSelectGame PROC
push offset DirBuffer
push TargetBufferSize
push offset TargetBuffer
push offset NOMenuOfSelectGame
push offset GameNameKey
push offset GameTargetNum
call GetPrivateProfileStringA ;"GameName"キー読み込み
push offset TargetBuffer
push 2040 ;「改造対象一覧を表示」直下のメニュー項目
push 0
push 2040
push MenuHandle
call ModifyMenuA ;メニュー項目をゲーム名に変更
push MFS_CHECKED + MF_BYCOMMAND
push 2040
push MenuHandle
call CheckMenuItem
push offset DirBuffer
push TargetBufferSize
push offset TargetBuffer
push offset NOMenuOfSelectGame
push offset GameNameKey
push offset GameTargetNum
call GetPrivateProfileStringA ;"GameName"キー読み込み
push offset TargetBuffer
push 2041 ;「改造直実行」直下のメニュー項目
push 0
push 2041
push MenuHandle
call ModifyMenuA ;メニュー項目をゲーム名に変更
push MFS_CHECKED + MF_BYCOMMAND
push 2041
push MenuHandle
call CheckMenuItem
push offset TargetBuffer
push 3502
push hwnd_
call SetDlgItemTextA
mov eax, GameCountBuf3
dec eax
push 0
push eax
push LB_SETCURSEL
push 3505 ;ListBoxのID
push hwnd_
call SendDlgItemMessageA ;リストボックスの選択項目変更
ret
MenuOfSelectGame ENDP
DlgProcedure ENDP
;*************************************************************************************************
;CDチェックメインルーチン
;*************************************************************************************************
CheckMain:
push CDCheckSkip ;CDチェックのスキップが選択されているかチェック
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz Goal
push mb_ok - 30h ;アイコンを付けるパラメータを除去
push offset information
push offset first ;開始メッセージ
push hwnd_
Call MessageBoxA
Retry:
mov ebx, 41h ;41は"A"のASCII値なので「mov ebx ,'A'」でも可
jmp Check
Increment:
mov eax, ebx ;ドライブ文字を表す値を別のレジスタに転送
add eax, 01 ;インクリメントして(inc eaxでも可)
mov ebx, eax ;次のドライブ文字を表す値に変更
Check: ;CDドライブチェック
mov ecx, ebx
cmp ecx, 5Ah ;5Aは"Z"のASCII値
jg Error ;Zドライブ以降はジャンプ
;jaでも動作上は問題ありません
mov edx, ebx
push edx ;ドライブ文字を表す値
push offset drive
push offset DrivePath ;作成される文字列の格納先
Call _wsprintfA ;ドライブパス作成
add esp,0Ch
push offset DrivePath
Call GetDriveTypeA ;返り値についてはBlueAshさんのチュートリアル参照
cmp eax, 5 ;EAXレジスタに格納された返り値を元にCDドライブかの判断
jne Increment ;CDドライブ以外は次のドライブへ
je Nomal
Error:
push mb_ok ;一般の警告音
Call MessageBeep
push mb_retrycancel + 10h ;アイコンを付けるパラメータを追加
push offset notice
push offset NoCD ;警告メッセージ
push hwnd_
Call MessageBoxA
cmp eax ,idretry
je Retry ;再試行へ
;以下「キャンセル」が押された場合の処理
Backdoor: ;CDチェック回避のバックドアを、過去の実例から再現しました
Push vk_shift ;シフトキー
Call GetAsyncKeyState ;キーが押されたかチェックしてEAXレジスタに値を返す
test ah,80h ;キーが現在押されていればah=80hで演算結果(論理積)は80h
jz Close ;押されていなければ終了処理へ
jmp Goal ;押されていればCDチェックをスキップ
Nomal:
Push 20h ;メッセージ(問い合わせ)のサウンド
Call MessageBeep
push mb_yesno + 20h ;アイコンを付けるパラメータを追加
push offset ask
push offset DrivePath ;ドライブパスを表示
push hwnd_
Call MessageBoxA
cmp eax,idno ;「いいえ」を押したか?
je Increment ;次のCDドライブを探す
CDidentify: ;CD認証をはじめます
push nFileSystemNameSize ;不要なので0をPUSHしている
push lpFileSystemNameBuffer ;同上
push offset lpFileSystemFlags ;実際にはこのポインタは不要です
push offset lpMaximumComponentLength ;同上
push lpVolumeSerialNumber
push dwcVolumeNameSize ;文字単位で100h(256)にしましたが104hでも構いません
push offset lpVolumeNameBuffer ;取得するボリュームラベル格納先
push offset DrivePath
Call GetVolumeInformationA ;CDドライブのボリュームラベルを取得
test eax ,eax ;返り値をチェック
jnz VolNameCheck ;ボリュームラベル名チェックへ
push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset NoVolume ;ボリュームラベルが取得できないのはCDドライブにCDが無いから
push hwnd_
Call MessageBoxA
jmp Increment ;次のドライブへ
VolNameCheck: ;ボリュームラベルチェック
push offset lpVolumeNameBuffer
push offset VolumeName ;「USAPYON」
Call lstrcmpA ;2つの文字列を比較
test eax ,eax
jz IDCheck ;CD認証用ファイルチェックへ
push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset VolumeWrong ;CDドライブのボリュームラベルが「USAPYON」ではない
push hwnd_
Call MessageBoxA
jmp Increment ;次のドライブへ
IDCheck:
push offset IDfile
push offset DrivePath
push offset file
push offset FilePath
Call _wsprintfA ;CD認証用ファイル「usapyon.dat」のパスを作成
add esp,10h
FileExistence: ;CD認証ファイルの存在チェック
push offset dwFileAttributes ;WIN32_FIND_DATA構造体へのポインタ
push offset FilePath
Call FindFirstFileA ;CDドライブのルートに「usapyon.dat」があるか?
cmp eax,0FFFFFFFFh ;ファイル「usapyon.dat」が存在しない(エラーが返された)
je NoIDfile
mov FindFileHandle ,eax ;返り値の検索ハンドルを退避
push handle ;以下でファイルハンドルを取得します
push file_attribute_normal
push open_existing
push lpsecurity_attribute
push file_share_read
push generic_read
push offset FilePath
Call CreateFileA ;この関数はファイルの存在チェックにも使用可能です
mov FileHandle,eax ;返り値のファイルハンドルを退避
jmp IDsafe
NoIDfile:
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset IDwrong ;CD認証失敗
push hwnd_
Call MessageBoxA
jmp Increment ;次のドライブへ
IDsafe:
Push 40h ;メッセージ(情報)のサウンド
Call MessageBeep
push mb_ok - 30h + 40h ;アイコンを付けるパラメータを変更
push offset information
push offset IDthrough
push hwnd_
Call MessageBoxA
;以下ファイルサイズチェック
;FileSize: ;コードを分かりやすくするためのラベルで実際には使用しない
push 0 ;ファイルサイズがFFFFFFFFhバイト以上の場合は必要
push FileHandle
Call GetFileSize
cmp eax,TrueSize ;ファイルサイズは9999バイトか比較
je Sizesafe
Sizeout:
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset SizeWrong ;CD認証ファイルのサイズが適合しない
push hwnd_
Call MessageBoxA
jmp Increment ;次のドライブへ
Sizesafe:
mov eax ,dwFileAttributes
and al ,01 ;CD認証ファイルは読み取り専用属性かチェック
jnz Goal
push mb_ok
push offset notice
push offset ReadOnly ;読み取り専用属性でない
push hwnd_
Call MessageBoxA
jmp Increment ;次のドライブへ
;*************************************************************************************************
;CDチェックMCI関連処理部分ルーチン
;*************************************************************************************************
Goal:
push CheckWav ;WAV再生が選択されているかチェック
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz NOCDDevice
push CheckMidi ;MidiのBGMが選択されているかチェック
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz NOCDDevice
push offset dwCallback ;MCI_OPEN_PARMS構造体のポインタ
push MCI_OPEN_TYPE ;コマンド処理用フラグ
push MCI_OPEN ;デバイスをオープン
push wDeviceIDOPEN ;デバイスをオープンする際は不要(NULL)
mov dword ptr [lpstrDeviceType], offset DeviceName ;デバイス名格納アドレスを転送
call mciSendCommandA
test eax, eax ;デバイスのオープンに成功したら戻り値は0
jne NOCDDevice
push 0 ;以下CDメディアの存在をチェック
push 8h ;変数MediaPresentのサイズを再指定
push offset MediaPresent
push offset CDstatus
call mciSendStringA
push offset MediaPresent ;CDメディアが存在すれば文字列"true"が返される
push offset MediaSafe
Call lstrcmpA
test eax ,eax
jne NoMedia
push 0 ;以下トラックベースでの再生を設定(mciSendCommandA関数でも可)
push 0 ;トラックベースでなければ分ベースになる
push 0
push offset SetTrack
call mciSendStringA
;以下でCD再生開始
push 0 ;NULL
push 0 ;ゼロサイズ
push 0 ;ポインタだがNULL可
push offset PlayCDaudio
call mciSendStringA
push mb_ok - 30h
push offset information
push offset SizeGood ;「ゲームCDが認証されました」
push hwnd_
Call MessageBoxA
jmp CDStop
NOCDDevice:
call MidiStart ;MIDI再生用サブルーチンの呼び出し
jmp Close
NoMedia:
Push 40h
Call MessageBeep
push mb_ok - 30h + 40h
push offset information
push offset MediaErr ;ゲームCD認証兼CDメディア確認エラーのメッセージ
push hwnd_
Call MessageBoxA
jmp CDClose
CDStop:
push offset dwCallback
push MCI_WAIT
push MCI_STOP
push wDeviceID
call mciSendCommandA ;CD再生を停止
CDClose:
push offset dwCallback
push MCI_NOTIFY
push MCI_CLOSE
push wDeviceID
call mciSendCommandA ;cdaudioデバイスをクローズ
Close:
push FindFileHandle
Call FindClose ;ファイル検索ハンドルをクローズ
push FileHandle
Call CloseHandle ;ファイルハンドルをクローズ
Last:
jmp BacktoDLG ;ダイアログに戻る
;push 0 ;親プロセスに返す終了コード(無意味)
;.invoke .win32 'KERNEL32.ExitProcess' ;APIを直接呼び出す例
;Call ExitProcess ;ダイアログに処理を戻すため使わない
MidiStart PROC ;■■■MIDI・WAV再生用サブルーチン■■■
push CheckWav ;WAV再生が選択されているかチェック
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jnz SelectMidi
mov ebx, offset SetWAV ;こちらを使えば「usapyon.wav」を再生します。
mov esi, offset WavPlay ;WAV再生メッセージ
jmp Midi_Wav_Play
SelectMidi:
mov ebx, offset SetMidi
mov esi, offset DeviceErr ;デバイスエラー兼MIDI再生メッセージ
Midi_Wav_Play:
mov edi, offset mciSendStringA ;汎用レジスタにロードして複数回利用する例
push 0 ;以下MIDI・WAファイルの再生を設定(mciSendCommandA関数でも可)
push 0
push 0
push ebx ;MIDI・WAVを指定
call edi ;mciSendStringA
push 0 ;以下でMIDI・WAVファイルの再生開始
push 0
push 0
push offset PlayMidi
call edi ;mciSendStringA
push mb_ok - 30h ;アイコンを除去しないとウィンドウズのイベントサウンドが再生される
push offset information
push esi ;メッセージ格納先ポインタを指定
push hwnd_
Call MessageBoxA
;push 0BB8h ;WAVファイルの再生時に上のメッセージボックスを使わない場合は、
;call Sleep ;再生時間を取得してその分プロセスを停止し、WAVを終わりまで再生させる
push 0 ;以下MIDI・WAVファイルの再生を停止
push 0
push 0
push offset StopMidi
call edi ;mciSendStringA
push 0 ;以下でMIDI・WAVファイルのデバイスをクローズ
push 0
push 0
push offset CloseMidi
call edi ;mciSendStringA
ret
MidiStart ENDP
;*************************************************************************************************
;CDチェック以外の付属機能
;*************************************************************************************************
FixTopWindow: ;■■■最前面表示処理■■■
push MF_BYCOMMAND
push MenuTop
push MenuHandle
call GetMenuState
cmp al,MFS_CHECKED
je BringToBehind
push MF_BYCOMMAND + MFS_CHECKED
push MenuTop
push MenuHandle
call CheckMenuItem
push SWP_NOSIZE + SWP_NOMOVE
push 0
push 0
push 0
push 0
push HWND_TOPMOST
push hwnd_
call SetWindowPos
jmp BacktoDLG
BringToBehind:
push MF_BYCOMMAND + MFS_UNCHECKED
push MenuTop
push MenuHandle
call CheckMenuItem
push SWP_NOSIZE + SWP_NOMOVE
push 0
push 0
push 0
push 0
push HWND_BOTTOM
push hwnd_
call SetWindowPos
push SWP_NOSIZE + SWP_NOMOVE
push 0
push 0
push 0
push 0
push HWND_TOP
push hwnd_
call SetWindowPos
jmp BacktoDLG
AtoIConv: ;■■■10進数列−16進数値変換処理■■■
push Radio16 ;「16」が選択されているかチェック
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz AtoIConv16
push 1 ;符号付き整数を指定
push offset DummyStrage ;Bool変数のポインタ
push EDIT_INT ;コントロールID
push hwnd_ ;ダイアログボックスのハンドル
call GetDlgItemInt ;符号付き整数以外の入力は総て値0と認識します
push eax ;16進数値に変換された入力文字列
push offset atoi
push offset SUbCheckBuf ;作成される文字列の格納先
Call _wsprintfA ;数値を文字列のコメントに変換
add esp,0Ch
push offset SUbCheckBuf
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA ;コメントを表示
jmp BacktoDLG
AtoIConv16: ;■■■16進数列−10進数値変換処理■■■
push 20h ;バッファ最大文字数
push offset SUbCheckBuf3 ;文字列格納バッファのポインタ
push EDIT_INT ;コントロールID
push hwnd_ ;ダイアログボックスのハンドル
call GetDlgItemTextA
mov eax,offset SUbCheckBuf3
call HexAtoHexI
push eax ;16進数値に変換された入力文字列
push offset atoi16
push offset SUbCheckBuf3 ;作成される文字列の格納先
Call _wsprintfA ;数値を文字列のコメントに変換
add esp,0Ch
push offset SUbCheckBuf3
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA ;コメントを表示
jmp BacktoDLG
HexAtoHexI PROC ;変換処理サブルーチン(コード未整理)
push edx ;atoi関数、itoa関数についても参照して下さい
push ebx
push ecx
HAtoHI1:
jmp HAtoHI3
HAtoHI2:
inc eax
HAtoHI3:
cmp byte ptr [eax],32
je HAtoHI2
cmp byte ptr [eax],9
je HAtoHI2
cmp byte ptr [eax],43
jne HAtoHI4
inc eax
jmp HAtoHI5
HAtoHI4:
cmp byte ptr [eax],45
jne HAtoHI6
or ecx,-1
inc eax
HAtoHI6:
HAtoHI5:
xor edx,edx
jmp HAtoHI8
HAtoHI7:
shl edx,4
cmp byte ptr [eax],48
jl HAtoHI9
cmp byte ptr [eax],57
jg HAtoHI9
movsx ebx,byte ptr [eax]
add ebx,-48
add edx,ebx
jmp HAtoHI10
HAtoHI9:
cmp byte ptr [eax],65
jl HAtoHI11
cmp byte ptr [eax],70
jg HAtoHI11
movsx ebx,byte ptr [eax]
add ebx,-55
add edx,ebx
jmp HAtoHI10
HAtoHI11:
movsx ebx,byte ptr [eax]
add ebx,-87
add edx,ebx
HAtoHI10:
inc eax
HAtoHI8:
cmp byte ptr [eax],48
jl HAtoHI12
cmp byte ptr [eax],57
jle HAtoHI7
HAtoHI12:
cmp byte ptr [eax],65
jl HAtoHI13
cmp byte ptr [eax],70
jle HAtoHI7
HAtoHI13:
cmp byte ptr [eax],97
jl HAtoHI14
cmp byte ptr [eax],102
jle HAtoHI7
HAtoHI14:
dec ecx
jne HAtoHI15
mov eax,edx
jmp HAtoHI17
HAtoHI15:
mov eax,edx
HAtoHI18:
HAtoHI17:
pop ecx
pop ebx
pop edx
ret
HexAtoHexI ENDP
CheckSub: ;■■■ドライブタイプ判定処理■■■
push 20h ;バッファ最大文字数
push offset SUbCheckBuf2 ;文字列格納バッファのポインタ
push EDIT_DRIVE ;コントロールID
push hwnd_ ;ダイアログボックスのハンドル
call GetDlgItemTextA
cmp eax, 3 ;戻り値は入力された文字数
ja NotDriveletter
mov eax, dword ptr [offset SUbCheckBuf2]
cmp al, 41h ;41h="A"
jb NotDriveletter
cmp al, 7Ah ;7Ah="z"
ja NotDriveletter
cmp al, 5Bh ;"["
je NotDriveletter
cmp al, 5Ch ;"\"
je NotDriveletter
cmp al, 5Dh ;"]"
je NotDriveletter
cmp al, 5Eh ;"^"
je NotDriveletter
cmp al, 5Fh ;"_"
je NotDriveletter
cmp ah, 3Ah ;":"
jne NotDriveletter
shr eax, 10h
cmp al, 0h ;未入力
je CDCheck2nd
cmp al, 5Ch ;"\"
je CDCheck2nd
NotDriveletter: ;wsprintf関数で入力されたドライブパス文字列をコメントに追加可能
;Push 40h
;Call MessageBeep
push mb_ok - 30h + 40h
push offset information
push offset NOTDrive
push hwnd_
Call MessageBoxA
jmp BacktoDLG
CDCheck2nd:
push offset SUbCheckBuf2
Call GetDriveTypeA
cmp eax, 1
je DriveReturn1
cmp eax, 3
je DriveReturn3
cmp eax, 2
je DriveReturn2
cmp eax, 5
je DriveReturn5
push offset Drive_Unknown
DriveReturn1:
push offset Drive_NON
jmp CheckResult
DriveReturn3:
push offset Drive_Hard
jmp CheckResult
DriveReturn2:
push offset Drive_Fix
jmp CheckResult
DriveReturn5:
push offset Drive_CD
CheckResult:
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA
jmp BacktoDLG ;ダイアログに戻る
AboutBox: ;■■■バージョン情報についての表示■■■
push offset AboutNotice
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA
jmp BacktoDLG
EDIT_TEXT_OUT_Clear: ;■■■メインエディットボックス選択領域をクリア■■■
mov eax, WM_CLEAR
jmp EDIT_TEXT_OUT_MAIN
EDIT_TEXT_OUT_UNDO: ;■■■メインエディットボックスでUNDO■■■
mov eax, WM_UNDO
jmp EDIT_TEXT_OUT_MAIN
EDIT_TEXT_OUT_Cut: ;■■■メインエディットボックスでCUT■■■
mov eax, WM_CUT
jmp EDIT_TEXT_OUT_MAIN
EDIT_TEXT_OUT_Copy: ;■■■メインエディットボックスでCOPY■■■
mov eax, WM_COPY
jmp EDIT_TEXT_OUT_MAIN
EDIT_TEXT_OUT_Paste: ;■■■メインエディットボックスでPASTE■■■
mov eax, WM_PASTE
EDIT_TEXT_OUT_MAIN:
push 0
push 0
push eax
push hEdit
call SendMessageA
jmp BacktoDLG
EDIT_TEXT_OUT_ALL: ;■■■エディットコントロール内全テキストを選択■■■
call SelectALLtext
jmp BacktoDLG
SelectALLtext PROC
push -1
push 0
push EM_SETSEL
push hEdit
call SendMessageA
ret
SelectALLtext ENDP
EDIT_TEXT_OUT_ALLClear: ;■■■エディットコントロール内全テキストをクリア■■■
call SelectALLtext
jmp EDIT_TEXT_OUT_Clear
;*************************************************************************************************
;CD−DA及び各種メディアファイルの操作ルーチン
;*************************************************************************************************
CD_Play: ;■■■トラック指定によるCD再生■■■
push 0 ;符号なし整数を指定
push offset DummyStrage ;Bool変数のポインタ
push EDIT_CDTRACK ;コントロールID
push hwnd_ ;ダイアログボックスのハンドル
call GetDlgItemInt ;符号なし整数以外の入力は総て値0と認識します
push eax ;数値に変換された入力文字列
push offset TrackMessage
push offset MCIMessBuf ;作成される文字列の格納先
Call _wsprintfA ;数値を文字列のコメントに変換
add esp,0Ch
push 0 ;NULL
push 0 ;ゼロサイズ
push 0 ;ポインタだがNULL可
push offset OpenMessage
call mciSendStringA
push 0 ;以下トラックベースでの再生を設定(mciSendCommandA関数でも可)
push 0 ;トラックベースでなければ分ベースになる
push 0
push offset SetTrack
call mciSendStringA
push 01F4h ;再生開始までにバッファを置いて、再生エラーが起きる可能性に対処
call Sleep
push hwnd_ ;MM_MCINOTIFYメッセージを返すウィンドウハンドル
push 0
push 0
push offset MCIMessBuf
call mciSendStringA
jmp BacktoDLG
CD_Stop: ;■■■CD停止処理■■■
call CD_END ;「Stop」ボタン押下時とアプリ終了時にCD再生停止とデバイスのクローズを行う
jmp BacktoDLG
CD_END PROC
push 0
push 0
push 0
push offset StopCD
call mciSendStringA
push 0
push 0
push 0
push offset CloseCD
call mciSendStringA
ret
CD_END ENDP
CD_Eject: ;■■■CD取り出し処理■■■
call CD_END ;CD停止処理
push 0
push 0
push 0
push offset EjectCD
call mciSendStringA
jmp BacktoDLG
CD_Insert: ;■■■CD挿入処理■■■
push 0
push 0
push 0
push offset InsertCD
call mciSendStringA
jmp BacktoDLG
AVIStart1: ;■■■マルチメディアファイル再生処理■■■
mov edi, offset DefKeyM1
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart2:
mov edi, offset DefKeyM2
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart3:
mov edi, offset DefKeyM3
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart4:
mov edi, offset DefKeyM4
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart5:
mov edi, offset DefKeyM5
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart6:
mov edi, offset DefKeyM6
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIStart7:
mov edi, offset DefKeyM7
mov esi, offset AVIPlayMessage
jmp AVIStartMain
AVIResume: ;■■■マルチメディアファイル再開処理■■■
mov esi, offset AVIResumeMessage
jmp AVIStartMain2
AVIPause: ;■■■マルチメディアファイル一時停止処理■■■
mov esi, offset AVIPauseMessage
jmp AVIStartMain2
AVIStop: ;■■■マルチメディアファイル停止処理■■■
push INIBuffer ;AVIStartMain2重複処理:サブルーチン化で不具合有り
push offset AVIStopMessage
push offset DirBuffer2
call _wsprintfA
add esp,0Ch
push 0
push 0
push 0
push offset DirBuffer2
call mciSendStringA
mov esi,offset AVICloseMessage ;■■■デバイスクローズ処理■■■
jmp AVIStartMain2
AVIStartMain:
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push offset edi
push offset DefSection
call GetPrivateProfileStringA
AVIStartMain2:
push 104h ;ここではパス名のなので104hに再定義
push INIBuffer
push INIBuffer
call GetShortPathNameA
push INIBuffer
push esi
push offset DirBuffer2
call _wsprintfA
add esp,0Ch
push 0
push 0
push 0
push offset DirBuffer2
call mciSendStringA
jmp BacktoDLG
SndVol32: ;■■■Sndvol32.exe起動処理■■■
push 104h ;ここではパス名のなので104hに再定義
push offset WinPath
push offset WinPath
call GetShortPathNameA
push offset WinPath
push offset SndVol
push offset WinAppliPath
call _wsprintfA
add esp,0Ch
push SW_SHOWNORMAL
push 0
push 0
push offset WinAppliPath
push 0
push hwnd_
call ShellExecuteA
jmp BacktoDLG
;*************************************************************************************************
;URL展開・アプリ起動処理
;*************************************************************************************************
URL_DT: ;■■■URL展開処理■■■
mov esi, offset URL_1
jmp URL_MAIN
URL_DT2:
mov esi, offset URL_2
jmp URL_MAIN
URL_MSDN:
mov esi, offset URL_3
jmp URL_MAIN
URL_MSDN2:
mov esi, offset URL_4
jmp URL_MAIN
URL_GAME:
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push offset GameSiteKey
push offset GameTargetNum
call GetPrivateProfileStringA
mov esi, INIBuffer
URL_MAIN:
push SW_MAXIMIZE
push 0
push 0
push esi
push 0
push hwnd_
call ShellExecuteA
jmp BacktoDLG
INIOpen: ;■■■INIファイルオープン処理■■■
push 104h ;ここではパス名のなので104hに再定義
push offset WinPath
push offset WinPath
call GetShortPathNameA
push offset WinPath
push offset Notepad
push offset WinAppliPath
call _wsprintfA
add esp,0Ch
push SW_MAXIMIZE
push 0
push offset DirBuffer
push offset WinAppliPath
push 0
push hwnd_
call ShellExecuteA
jmp BacktoDLG
ChangeFont: ;■■■フォント変更処理■■■
push 1
push 0
push WM_SETFONT
push EDIT_TEXT_OUT
push hwnd_
call SendDlgItemMessageA
jmp BacktoDLG
UndoFont: ;■■■フォント変更処理2■■■
push 1
push dword ptr [FontHandle]
push WM_SETFONT
push EDIT_TEXT_OUT
push hwnd_
call SendDlgItemMessageA
jmp BacktoDLG
MemoStart: ;■■■テキストエディタ起動処理■■■
mov esi,offset DefKey
jmp StartMain
HexStart: ;■■■ヘキサエディタ起動処理■■■
mov esi,offset DefKey3
jmp StartMain
CalStart: ;■■■16進電卓起動処理■■■
mov esi,offset DefKey4
jmp StartMain
Appli1Start: ;■■■登録アプリ1起動処理■■■
mov esi,offset DefKey5
jmp StartMain
Appli2Start: ;■■■登録アプリ2起動処理■■■
mov esi,offset DefKey6
jmp StartMain
Appli3Start: ;■■■登録アプリ3起動処理■■■
mov esi,offset DefKey7
jmp StartMain
Appli4Start: ;■■■登録アプリ4起動処理■■■
mov esi,offset DefKey8
jmp StartMain
Appli5Start: ;■■■登録アプリ5起動処理■■■
mov esi,offset DefKey9
jmp StartMain
Appli6Start: ;■■■登録アプリ6起動処理■■■
mov esi,offset DefKey10
jmp StartMain
Appli7Start: ;■■■登録アプリ7起動処理■■■
mov esi,offset DefKey11
StartMain:
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push esi
push offset DefSection
call GetPrivateProfileStringA
push 104h ;ここではパス名のなので104hに再定義
push INIBuffer
push INIBuffer
call GetShortPathNameA
push SW_SHOWNORMAL
push 0
push 0
push INIBuffer
push 0
push hwnd_
call ShellExecuteA
jmp BacktoDLG
;*************************************************************************************************
;ゲーム改造関連ルーチン
;*************************************************************************************************
CheatEnable PROC
push BTN_ChInfoUpdate
push hwnd_
call GetDlgItem ;改造関連ボタンの有効化
push 1 ;True
push eax
call EnableWindow
push BTN_CheatNow
push hwnd_
call GetDlgItem
push 1 ;True
push eax
call EnableWindow
push MF_BYCOMMAND + MF_ENABLED ;改造関連メニューの有効化
push MenuChInfoUpdate
push MenuHandle
call EnableMenuItem
push MF_BYCOMMAND + MF_ENABLED ;改造関連メニューの有効化
push MenuCheatSelected
push MenuHandle
call EnableMenuItem
push MF_BYCOMMAND + MF_ENABLED ;改造関連メニューの有効化
push SiteGame
push MenuHandle
call EnableMenuItem
ret
CheatEnable ENDP
ListSelect: ;■■■選択ゲームの変更認識処理■■■
shr eax,10h
cmp eax,LBN_SELCHANGE
jne BacktoDLG
call CheatEnable
jmp SelectGameFromList
FUI:
push offset FUIList
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA
jmp BacktoDLG
GameSectionUpdate: ;■■■選択中ゲームのGAMEセクション更新処理■■■
push vk_shift ;バックドア
call GetAsyncKeyState
cmp ah,80h
jz GameSectionUpdate2
push mb_yesno + 20h ;アイコンを付けるパラメータを追加
push offset askupdate
push offset CheatInfoUpdate
push hwnd_
Call MessageBoxA
cmp eax,idno ;「いいえ」を押したか?
je BacktoDLG
GameSectionUpdate2:
mov ecx, 1FFFh
mov ebx, INIBuffer
INIBufferClear:
mov dword ptr [ebx],0
add ebx, 4
loop INIBufferClear
push 7FFFh
push INIBuffer
push EDIT_TEXT_OUT
push hwnd_
call GetDlgItemTextA
push offset DirBuffer
push INIBuffer
push offset GameTargetNum
call WritePrivateProfileSectionA
mov esi, offset GameTargetNum
jmp INIindicateMain
jmp BacktoDLG
SelectGameFromList: ;■■■改造情報表示処理■■■
push 0
push 0
push LB_GETCURSEL
push 3505 ;ListBoxのID
push hwnd_
call SendDlgItemMessageA
mov GameCountBuf3, eax
inc eax
push eax
push offset TargetGameFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
mov edi, offset GameTargetNum ;「改造対象#」で設定したゲーム名
push offset DirBuffer
push TargetBufferSize
push offset TargetBuffer
push offset NOkey
push edi
push offset TargetSection
call GetPrivateProfileStringA
push offset TargetBuffer
push 3502
push hwnd_
call SetDlgItemTextA
inc GameCountBuf3
push GameCountBuf3
push offset GameSectionFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
mov esi, offset GameTargetNum
call MenuOfSelectGame
jmp INIindicateMain
NowSelectGame: ;■■■現在選択・改造中のゲーム表示処理■■■
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey2
push offset GameNameKey
push offset GameTargetNum
call GetPrivateProfileStringA
push INIBuffer
push offset SelectGameIs
push offset SelectGameBuf
call _wsprintfA
add esp,0Ch
push offset SelectGameBuf
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA
jmp BacktoDLG
INIindicate: ;■■■INIファイルの基本設定・改造コード表示処理■■■
sub eax, MenuChInfo
inc eax
mov GameCountBuf3, eax
push eax
push offset GameSectionFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
mov esi, offset GameTargetNum
call MenuOfSelectGame
call CheatEnable
jmp INIindicateMain
INIindicateGame:
mov esi, offset TargetSection
jmp INIindicateMain
INIindicateDef:
mov esi, offset DefSection
INIindicateMain:
mov edi, INIBuffer
push offset DirBuffer ;INIファイルのパス
push INIBufferSize ;取得セクション内容格納バッファのサイズ
push INIBuffer ;同ポインタ
push esi ;目的のセクション名
call GetPrivateProfileSectionA;指定セクションの内容を総て取得
push offset Dummy ;エディットコントロールをダミーデータでクリア
push EDIT_TEXT_OUT
push hwnd_
call SetDlgItemTextA ;エディットコントロールに文字を送る別の方法
mov dword ptr [KeyReturn],00000A0Dh ;強制改行の準備(\r\n不可)
NextLine:
push edi ;INIBuffer
call lstrlenA
mov esi,eax
push edi ;INIBuffer
push 0
push EM_REPLACESEL
push hEdit
call SendMessageA
push offset KeyReturn
push 0
push EM_REPLACESEL
push hEdit
call SendMessageA ;強制改行
add edi,esi
inc edi
cmp byte ptr [edi], 0 ;これ以降文字が無いか
je LineEnd
mov eax, dword ptr [INIBuffer]
add eax, INIBufferSize
cmp edi, eax
jb NextLine
LineEnd:
push -104h ;縦方向スクロール行数
push 0
push EM_LINESCROLLL
push hEdit
call SendMessageA ;エディットコントロールの最初の行まで戻す
jmp BacktoDLG ;ダイアログに戻る
GameCheatFromBTN:
push GameCountBuf3
push offset GameSectionFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
jmp CheatSelectedGame
GameCheat: ;■■■ゲーム改造実行処理の準備(対象ファイルのオープン)■■■
sub eax, MenuCheat
inc eax
mov GameCountBuf3, eax
push eax
push offset GameSectionFormat
push offset GameTargetNum
call _wsprintfA
add esp,0Ch
call CheatEnable
CheatSelectedGame:
mov esi,offset GameTargetNum
mov dword ptr [GameSectionNum],esi ;ゲームセクションの特定
call MenuOfSelectGame
jmp GameCheatMain
GameCheatMain:
mov dword ptr [offset CodeCountBuf2], 1 ;コード番号を1にセット
;PreCheat:
push offset DirBuffer
push 104h ;INIBufferSizeでは不整合が生じてエラー
push offset PathBuffer ;PathBuffer=104h
push offset NOkey
push offset SaveDataPos
push dword ptr [GameSectionNum]
call GetPrivateProfileStringA ;”SaveData”キー読み込み
push 104h ;ここではパス名のなので104hに再定義
push offset PathBuffer
push offset PathBuffer
call GetShortPathNameA
push file_attribute_normal
push offset PathBuffer
call SetFileAttributesA ;読み取り専用属性を外してファイル属性をノーマルに
push handle
push file_attribute_normal
push open_existing
push lpsecurity_attribute
push file_share_read
push generic_read + generic_write
push offset PathBuffer
Call CreateFileA
mov FileHandle,eax ;返り値のファイルハンドルを退避
cmp eax,0FFFFFFFFh ;セクション名の間違いもここでフォロー
jnz SaveExist
SaveError: ;ファイルハンドル取得失敗
mov dword ptr [CodeErrorMess], offset SaveWrong
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz CheatFinish2
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset SaveWrong
push hwnd_
Call MessageBoxA
jmp CheatFinish2
SaveExist: ;■■■対象ファイルのバックアップ作成処理■■■
push offset PathBuffer
push offset BackupName
push offset PathBuffer2
call _wsprintfA
add esp,0Ch
push CheckBackUp
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jnz SaveExist2
push 1 ;True
push offset PathBuffer2
push offset PathBuffer
call CopyFileA
call GetLastError
cmp eax, ERROR_FILE_EXISTS
jnz SaveExist2
Push 20h ;メッセージ(問い合わせ)のサウンド
Call MessageBeep
push mb_yesno + 20h ;アイコンを付けるパラメータを追加
push offset information
push offset BackupRewrite
push hwnd_
Call MessageBoxA
cmp eax,idno ;「いいえ」を押したか?
je SaveExist2
push 0 ;False
push offset PathBuffer2
push offset PathBuffer
call CopyFileA
SaveExist2: ;■■■メモリブロック確保と対象ファイルの読み込み■■■
push offset LowDateTime1
push offset LowDateTime2
push offset LowDateTime3
push FileHandle
call GetFileTime
push 0 ;ファイルサイズがFFFFFFFFhバイト以上の場合は必要
push FileHandle
Call GetFileSize
mov FileSize,eax
push FileSize
push GMEM_FIXED
Call GlobalAlloc
mov MemPtr,eax ;確保したメモリブロックのポインタを退避
cmp eax,0
jnz MemorySafe
mov dword ptr [CodeErrorMess], offset MemWrong
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz CheatFinish
Push mb_ok
Call MessageBeep
push mb_ok
push offset notice
push offset MemWrong
push hwnd_
Call MessageBoxA
jmp CheatFinish
MemorySafe:
push lpOverlapped
push offset lpNumberOfBytesRead
push FileSize
push MemPtr
push FileHandle
Call ReadFile
GetCode: ;■■■ゲーム改造コードの読み込みと型判定■■■
push dword ptr [offset CodeCountBuf2]
push offset CodeNameFormat
push offset CodeName
call _wsprintfA ;”Code#”文字列作成
add esp,0Ch
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push offset CodeName
push dword ptr [GameSectionNum]
call GetPrivateProfileStringA ;”Code#”読み込み
mov ecx, INIBuffer
mov edx, offset CodeStart
cmp byte ptr [ecx], 25h ;"%" ;置換型コードの判定
je CodeReplacePre
cmp byte ptr [ecx], 48h ;"H"
je HexView
Code1st:
mov bl,byte ptr [ecx]
mov byte ptr [edx], bl
inc edx
inc ecx
cmp byte ptr [ecx], 3Eh ;">" ;コード制御記号認識
je Code2nd
cmp byte ptr [ecx], 2Dh ;"-"
je Code3rdPre
cmp byte ptr [ecx], 24h ;"$" ;文字列型コードの判定
je Code3rdString1
jmp Code1st
Code2nd:
mov byte ptr [offset SerialMacro], 1 ;">"を用いた連続処理のフラグを成立させる
mov eax, offset CodeStart
call HexAtoHexI
mov dword ptr [offset CodeStart2], eax ;書き換え開始オフセットを変数「CodeStart2」として格納
mov edx, offset CodeEnd
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
cmp byte ptr [ecx], 2Fh
jbe CodeFormatError
Code2ndmain:
mov bl,byte ptr [ecx]
mov byte ptr [edx],bl
inc edx
inc ecx
cmp byte ptr [ecx], 2Dh ;"-" ;コード制御記号認識
je Code3rd
cmp byte ptr [ecx], 24h ;"$" ;エラー回避用(通常文字列連続処理は使用しない)
je Code3rdString2
cmp byte ptr [ecx], 26h ;"&" ;コード制御記号認識(XOR処理)
je CodeXOR
cmp byte ptr [ecx], 23h ;"#" ;コード制御記号認識(リバースエンディアン処理)
je CodeReverse
jmp Code2ndmain
CodeReverse: ;■■■格納データリバース処理■■■
mov eax, offset CodeEnd
call HexAtoHexI
mov dword ptr [offset CodeEnd2], eax ;書き換え終了オフセットを変数「CodeEnd2」として格納
mov ecx,dword ptr [offset CodeEnd2]
sub ecx,dword ptr [offset CodeStart2]
inc ecx
mov dword ptr [offset CharaFlag],ecx
mov esi, MemPtr
add esi, dword ptr [offset CodeEnd2]
mov edx, offset CodeFill2
ReverseFill:
mov bl, byte ptr [esi]
mov byte ptr [edx], bl
dec esi
inc edx
loop ReverseFill
jmp CheatMain
CodeXOR: ;■■■連続型XOR書き換え処理■■■
mov eax, offset CodeEnd
call HexAtoHexI
mov dword ptr [offset CodeEnd2], eax ;書き換え終了オフセットを変数「CodeEnd2」として格納
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
mov edi, offset CodeFillBuf
mov esi, offset CodeFill2
mov dx, word ptr [ecx]
mov word ptr [edi],dx
mov eax, edi
call HexAtoHexI
mov byte ptr [XORBuf], al
;xor ebx,ebx
XorMain2:
mov ebx, MemPtr
add ebx, dword ptr [CodeStart2]
mov al, byte ptr [XORBuf]
xor byte ptr [ebx],al
mov edi, dword ptr [CodeStart2]
cmp edi, dword ptr [CodeEnd2]
ja SerialError ;範囲指定ミスなので書き換えしない
push 0
push 0
push dword ptr [CodeStart2]
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesWritten
push 1h
push ebx
push FileHandle
Call WriteFile
cmp eax,0
jnz XORMain3
mov dword ptr [CodeErrorMess], offset WriteError2
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz BufClearPre
push mb_okcancel + 30h ;アイコンを付けるパラメータを追加
push offset CodeName
push offset WriteError2
push hwnd_
Call MessageBoxA
cmp eax,idcancel
je BufClearPre
XORMain3:
add dword ptr [CodeStart2], 1
cmp edi, dword ptr [CodeEnd2]
je BufClearPre
jmp XORMain2
HexView: ;■■■16進表示型コードの処理■■■
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
HexView2:
mov bl,byte ptr [ecx]
mov byte ptr [edx], bl
inc edx
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je HexView3
cmp byte ptr [ecx], 20h ;" "
je HexView3
cmp byte ptr [ecx], 3Bh ;";"
je HexView3
cmp byte ptr [ecx], 81h ;全角スペースの可能性
jmp HexView2
HexView3:
mov eax, offset CodeStart
call HexAtoHexI
mov dword ptr [offset CodeStart2], eax
mov eax,MemPtr
add eax, dword ptr [CodeStart2]
mov ecx,10h
HexViewLoop:
movsx edx, byte ptr [eax + 0Fh]
and edx, 0FFh
push edx
dec eax
loop HexViewLoop
push dword ptr [offset CodeStart2]
push offset HexIntFormat
push offset HexViewBuf
call _wsprintfA
add esp,4Ch
mov dword ptr [CodeErrorMess],offset HexViewBuf
call CodeError
mov eax,MemPtr
add eax, dword ptr [CodeStart2]
mov esi,offset HexViewStringBuf
mov ecx,10h
HexViewLoop2:
mov bl, byte ptr [eax]
mov byte ptr [esi],bl
inc esi
inc eax
loop HexViewLoop2
push offset HexViewStringBuf
push dword ptr [offset CodeStart2]
push offset HexASCIIFormat
push offset HexViewBuf2
call _wsprintfA
add esp,10h
mov dword ptr [CodeErrorMess],offset HexViewBuf2
call CodeError
jmp BufClearPre
CodeReplacePre: ;■■■置換型ゲーム改造コードの処理■■■
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
mov edx, offset ReplaceData
CodeReplace1:
mov bl,byte ptr [ecx]
mov byte ptr [edx], bl
inc edx
inc ecx
cmp byte ptr [ecx], 2Dh ;"-"
je CodeReplace2
cmp byte ptr [ecx], 3Eh ;">"
je CodeFormatError
jmp CodeReplace1
CodeReplace2:
push ecx ;取得文字列バッファのアドレスを退避
push offset ReplaceData
call lstrlenA
mov dword ptr [offset CharaFlag], eax ;入力文字数を退避させておき、書き換え時に参照
shr dword ptr [offset CharaFlag], 1 ;(AtoIで字数半減)入力16進数字列の字数が奇数になることはない
cmp dword ptr [offset CharaFlag],0
je ZeroCharaError
mov ecx, eax ;ループカウンタ
mov esi, offset ReplaceData
mov edi, offset CodeFillBuf
mov ebx, offset ReplaceData2
CodeReplace3:
mov dx, word ptr [esi]
mov word ptr [edi],dx
mov eax, edi
call HexAtoHexI
mov byte ptr [ebx], al ;置換対象内容の16進値を変数「ReplaceData2」として格納
inc ebx
inc esi
inc esi
loop CodeReplace3 ;必要回数の倍ループすることになる(問題がないので対処不要)
pop ecx ;取得文字列バッファのアドレスを退避
inc ecx ;"-"の次
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
mov edx, offset ReplaceFill
CodeReplace4:
mov bl,byte ptr [ecx]
mov byte ptr [edx], bl
inc edx
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je CodeReplace5
cmp byte ptr [ecx], 20h ;" "
je CodeReplace5
cmp byte ptr [ecx], 3Bh ;";"
je CodeReplace5
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je CodeReplace5
jmp CodeReplace4
CodeReplace5:
push offset ReplaceFill
call lstrlenA
mov dword ptr [offset CharaFlag2], eax ;入力文字数を退避させておき、書き換え時に参照
shr dword ptr [offset CharaFlag2], 1 ;(AtoIで字数半減)入力16進数字列の字数が奇数になることはない
cmp dword ptr [offset CharaFlag2],0
je ZeroCharaError
mov ecx, eax ;ループカウンタ(ReplaceDataサイズ/2)
mov esi, offset ReplaceFill
mov edi, offset CodeFillBuf
mov ebx, offset ReplaceFill2
CodeReplace6:
mov dx, word ptr [esi]
mov word ptr [edi],dx
mov eax, edi
call HexAtoHexI
mov byte ptr [ebx], al ;書き換え内容の16進値を変数「ReplaceFill2」として格納
inc ebx
inc esi
inc esi
loop CodeReplace6 ;必要回数の倍ループすることになる(問題がないので対処不要)
CodeReplaceMain:
push offset ReplaceFill2
call lstrlenA
cmp eax, dword ptr [offset CharaFlag]
jnz CodeReplaceMain2
jmp CodeReplaceMain3
CodeError PROC
mov dword ptr [KeyReturn],0A0D0A0Dh
push offset CodeName
push 0
push EM_REPLACESEL
push hEdit
call SendMessageA
push dword ptr [CodeErrorMess]
push 0
push EM_REPLACESEL
push hEdit
call SendMessageA
push offset KeyReturn
push 0
push EM_REPLACESEL
push hEdit
call SendMessageA ;強制改行
ret
CodeError ENDP
CodeReplaceMain2:
mov dword ptr [CodeErrorMess], offset SearchWrong2
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz CodeReplaceMain3
push mb_yesno + 20h ;アイコンを付けるパラメータを追加
push offset CodeName
push offset SearchWrong2
push hwnd_
Call MessageBoxA
cmp eax,idno ;「いいえ」を押したか?
je BufClearPre
CodeReplaceMain3:
mov edi,MemPtr
mov ecx,FileSize
mov esi,offset ReplaceData2
mov al, byte ptr [esi]
jmp SearchLoop
SearchLoopReturn:
dec ReplacePos
mov ecx, FileSize
sub ecx, ReplacePos
sub ecx, dword ptr [offset CharaFlag2]
dec ecx
mov edi, ReplacePos
inc edi
add edi, dword ptr [offset CharaFlag2]
cmp FileSize,edi
jbe BufClearPre
add edi, MemPtr
mov esi,offset ReplaceData2
mov al, byte ptr [esi]
SearchLoop:
repnz scasb ;置換元データとの一致箇所を探索
cmp ecx,0
jz SearchError
push ecx ;ファイルサイズ−置換元データと同一箇所の先頭オフセット−1を退避
push edi
push esi
dec edi
mov ecx, dword ptr [offset CharaFlag]
inc ecx ;比較精度を高める安全策(エラー回避に必須)
repz cmpsb ;置換元データとの完全一致を確認
cmp ecx,0
jz ReplaceDo
pop esi
pop edi
pop ecx
jmp SearchLoop
SearchError:
mov dword ptr [CodeErrorMess], offset SearchWrong
call CodeError
jmp CodeError2
ReplaceDo:
pop esi
pop edi
pop ecx ;オフセット復帰
dec edi
inc ecx
mov eax,FileSize
sub eax,ecx
mov ReplacePos, eax
push eax
push offset ReplacePosInfo
push offset ReplacePosString
Call _wsprintfA
add esp,0Ch
mov dword ptr [CodeErrorMess], offset ReplacePosString
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz ReplaceDo2 ;CodeError2へのジャンプ不可
push mb_ok
push offset CodeName
push offset ReplacePosString
push hwnd_
Call MessageBoxA
ReplaceDo2:
push 0
push 0
push ReplacePos ;置換元データと同一箇所のオフセット
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesWritten
push dword ptr [offset CharaFlag2]
push offset ReplaceFill2
push FileHandle
Call WriteFile
cmp eax,0
jnz SearchLoopReturn
mov dword ptr [CodeErrorMess], offset WriteError
call CodeError
jmp CodeError2
;■■■通常のゲーム改造コードの処理■■■
Code3rdPre:
mov byte ptr [offset SerialMacro], 0 ;">"を用いた連続処理のフラグをクリア
mov eax, offset CodeStart
call HexAtoHexI
mov dword ptr [offset CodeStart2], eax ;書き換え開始オフセットを変数「CodeStart2」として格納
mov edx, offset CodeFill
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 20h ;" "
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je ZeroCharaError
cmp byte ptr [ecx], 26h ;"&" ;コード制御記号認識(XOR処理)
je CodeFormatError
cmp byte ptr [ecx], 23h ;"#" ;コード制御記号認識(リバースエンディアン処理)
je CodeFormatError
jmp Code3rdmain
Code3rd:
mov eax, offset CodeEnd
call HexAtoHexI
mov dword ptr [offset CodeEnd2], eax ;書き換え終了オフセットを変数「CodeEnd2」として格納
mov edx, offset CodeFill
inc ecx
Code3rdmain:
mov bl, byte ptr [ecx]
mov byte ptr [edx], bl
inc edx
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je Code3rdFinish
cmp byte ptr [ecx], 20h ;" "
je Code3rdFinish
cmp byte ptr [ecx], 3Bh ;";"
je Code3rdFinish
cmp byte ptr [ecx], 81h ;全角スペースの可能性
je Code3rdFinish
cmp byte ptr [ecx], 2Bh ;"+"
je AddInt
jmp Code3rdmain
AddInt: ;■■■加算型ゲーム改造コードの処理■■■
cmp SerialMacro, 1
je CodeFormatError
push offset CodeFill
call lstrlenA
mov dword ptr [offset CharaFlag], eax ;入力文字数を退避させておき、書き換え時に参照
shr dword ptr [offset CharaFlag], 1 ;(AtoIで字数半減)入力16進数字列の字数が奇数になることはない
cmp dword ptr [offset CharaFlag],0
je ZeroCharaError
mov ecx, eax
mov esi, offset CodeFill
mov edi, offset CodeFillBuf
mov ebx, offset CodeFill2
dec ebx ;格納方式を逆にする場合
AddInt2:
mov eax, esi ;格納方式を逆にする場合
add eax, ecx ;格納方式を逆にする場合
mov dx, word ptr [eax] ;格納方式を逆にする場合
mov word ptr [edi],dx
mov eax, edi
call HexAtoHexI
mov byte ptr [ebx], al ;書き換え内容の16進値を変数「CodeFill2」として格納
inc ebx
dec esi ;格納方式を逆にする場合
loop AddInt2 ;必要回数の倍ループすることになる(問題がないので対処不要)
mov eax,dword ptr [offset CodeStart2]
add eax, MemPtr
mov ecx, dword ptr [eax]
add dword ptr [offset CodeFill2],ecx
jmp CheatMain
Code3rdString1: ;■■■文字列型ゲーム改造コードの処理■■■
mov eax, offset CodeStart
call HexAtoHexI
mov dword ptr [offset CodeStart2], eax ;書き換え開始オフセットを変数「CodeStart2」として格納
mov edx, offset CodeFill2
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
jmp Code3rdStringmain
Code3rdString2:
mov eax, offset CodeEnd
call HexAtoHexI
mov dword ptr [offset CodeEnd2], eax ;書き換え終了オフセットを変数「CodeEnd2」として格納
mov edx, offset CodeFill2
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je ZeroCharaError
cmp byte ptr [ecx], 3Bh ;";"
je ZeroCharaError
Code3rdStringmain:
mov bl, byte ptr [ecx]
mov byte ptr [edx], bl ;書き換え内容を変数「CodeFill2」として格納
inc edx
inc ecx
cmp byte ptr [ecx], 00h ;NULL ;文字列終了或いはコード制御記号認識
je Code3rdStringChara
;cmp byte ptr [ecx], 20h ;" " ;文字列に半角スペースが使われる可能性に対処
;je Code3rdStringChara
cmp byte ptr [ecx], 3Bh ;";"
je Code3rdStringChara
jmp Code3rdStringmain
Code3rdStringChara:
push offset CodeFill2
call lstrlenA
mov dword ptr [offset CharaFlag], eax ;入力文字数を退避させておき、書き換え時に参照
cmp dword ptr [offset CharaFlag],0
je ZeroCharaError
jmp CheatMain
Code3rdFinish: ;■■■ファイル書き換え用データを処理■■■
push offset CodeFill
call lstrlenA
mov dword ptr [offset CharaFlag], eax ;入力文字数を退避させておき、書き換え時に参照
shr dword ptr [offset CharaFlag], 1 ;(AtoIで字数半減)入力16進数字列の字数が奇数になることはない
cmp dword ptr [offset CharaFlag],0
je ZeroCharaError
mov ecx, eax
mov esi, offset CodeFill
mov edi, offset CodeFillBuf
mov ebx, offset CodeFill2
;dec ebx ;格納方式を逆にする場合
Code3rdFinish2:
;mov eax, esi ;格納方式を逆にする場合
;add eax, ecx ;格納方式を逆にする場合
;mov dx, word ptr [eax] ;格納方式を逆にする場合
mov dx, word ptr [esi] ;格納方式を逆にする場合不要
mov word ptr [edi],dx
mov eax, edi
call HexAtoHexI
mov byte ptr [ebx], al ;書き換え内容の16進値を変数「CodeFill2」として格納
inc ebx
;dec esi ;格納方式を逆にする場合
inc esi ;格納方式を逆にする場合不要
inc esi ;格納方式を逆にする場合不要
loop Code3rdFinish2 ;必要回数の倍ループすることになる(問題がないので対処不要)
CheatMain: ;■■■ファイル書き換え処理■■■
cmp SerialMacro, 1
jz CheatMain2
push 0
push 0
push dword ptr [CodeStart2]
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesWritten
push CharaFlag
push offset CodeFill2
push FileHandle
Call WriteFile
cmp eax,0
jnz BufClearPre
mov dword ptr [CodeErrorMess], offset WriteError
call CodeError
jmp CodeError2
CheatMain2: ;■■■連続型コードのファイル書き換え処理■■■
mov edi, dword ptr [CodeStart2]
add edi, dword ptr [offset CharaFlag]
dec edi
cmp edi, dword ptr [CodeEnd2]
ja SerialError
push 0
push 0
push dword ptr [CodeStart2]
push FileHandle
call SetFilePointer
push lpOverlapped
push offset lpNumberOfBytesWritten
push CharaFlag
push offset CodeFill2
push FileHandle
Call WriteFile
cmp eax,0
jnz CheatMain3
mov dword ptr [CodeErrorMess], offset WriteError2
call CodeError
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz BufClearPre
push mb_okcancel + 30h ;アイコンを付けるパラメータを追加
push offset CodeName
push offset WriteError2
push hwnd_
Call MessageBoxA
cmp eax,idcancel
je BufClearPre
CheatMain3:
movsx esi, byte ptr [offset CharaFlag]
add dword ptr [CodeStart2], esi
cmp edi, dword ptr [CodeEnd2]
je BufClearPre
jmp CheatMain2
CodeFormatError:
mov dword ptr [CodeErrorMess], offset NGCode
call CodeError
CodeError2:
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz BufClearPre
Push mb_ok
Call MessageBeep
push mb_ok
push offset CodeName
push dword ptr [CodeErrorMess] ;offset NGCode
push hwnd_
Call MessageBoxA
jmp BufClearPre
ZeroCharaError:
mov dword ptr [CodeErrorMess], offset CharaZero
call CodeError
jmp CodeError2
SerialError:
mov dword ptr [CodeErrorMess], offset SerialWrong
call CodeError
jmp CodeError2
BufClearPre: ;■■■書き換え後の後処理■■■
mov ecx, 40h
mov ebx, offset CodeFill
BufClear:
mov dword ptr [ebx],0 ;変数「CodeFill1」初期化(最適化としてはand命令が適切)
add ebx, 4
loop BufClear
mov ecx, 40h
mov ebx, offset CodeFill2
BufClear2:
mov dword ptr [ebx],0 ;変数「CodeFill2」初期化
add ebx, 4
loop BufClear2
mov ecx, 40h
mov ebx, offset ReplaceFill
BufClear3:
mov dword ptr [ebx],0 ;変数「ReplaceFill」初期化
add ebx, 4
loop BufClear3
mov ecx, 40h
mov ebx, offset ReplaceFill2
BufClear4:
mov dword ptr [ebx],0 ;変数「ReplaceFill2」初期化
add ebx, 4
loop BufClear4
mov ecx, 40h
mov ebx, offset ReplaceData
BufClear5:
mov dword ptr [ebx],0 ;変数「ReplaceData」初期化
add ebx, 4
loop BufClear5
mov ecx, 40h
mov ebx, offset ReplaceData2
BufClear6:
mov dword ptr [ebx],0 ;変数「ReplaceData2」初期化
add ebx, 4
loop BufClear6
mov dword ptr [offset CodeStart], 0 ;変数「CodeStart」初期化
mov dword ptr [offset CodeEnd], 0 ;変数「CodeEnd」初期化
mov dword ptr [offset CodeStart2], 0 ;変数「CodeStart2」初期化
mov dword ptr [offset CodeEnd2], 0 ;コード終了オフセット指定なしのケースにも対処
;8バイトクリアしないと無限書き込みのエラーを招く
mov dword ptr [offset CodeStart+4], 0 ;変数「CodeStart」初期化
mov dword ptr [offset CodeEnd+4], 0 ;変数「CodeEnd」初期化
mov dword ptr [offset CodeStart2+4], 0 ;変数「CodeStart2」初期化
mov dword ptr [offset CodeEnd2+4], 0 ;コード終了オフセット指定なしのケースにも対処
mov dword ptr [offset CodeFillBuf], 0
mov byte ptr [offset SerialMacro], 0
push offset DirBuffer
push 0
push offset GameCodeCount
push dword ptr [GameSectionNum]
call GetPrivateProfileIntA
mov esi, eax
inc dword ptr [offset CodeCountBuf2]
cmp esi, dword ptr [offset CodeCountBuf2]
jb CheatFinish
jmp GetCode ;次のコードへ
CheatFinish: ;■■■全コード処理終了後の処理■■■
push offset LowDateTime1
push offset LowDateTime2
push offset LowDateTime3
push FileHandle
call SetFileTime
push MemPtr
call GlobalFree
push FileHandle
call CloseHandle
CheatFinish2:
mov dword ptr [CodeErrorMess], offset CheatDone
call CodeError
push CheckUseHexEditor
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jnz CheatFinish2a
push offset DirBuffer
push INIBufferSize
push INIBuffer
push offset NOkey
push offset DefKey3
push offset DefSection
call GetPrivateProfileStringA
push 104h ;ここではパス名のなので104hに再定義
push INIBuffer
push INIBuffer
call GetShortPathNameA
push SW_SHOWNORMAL
push 0
push offset PathBuffer
push INIBuffer
push 0
push hwnd_
call ShellExecuteA ;ヘキサエディタでファイルを展開
CheatFinish2a:
push CheckNoWarning
push hwnd_
call IsDlgButtonChecked ;チェックボタンの状態を取得
dec eax
jz BacktoDLG
Push mb_ok
Call MessageBeep
push mb_ok - 30h + 40h
push offset information
push offset CheatDone ;改造完了のメッセージ
push hwnd_
Call MessageBoxA
jmp BacktoDLG
ends ;■■■コード終了■■■
end Start ;■■■コード開始は「Start」から■■■
;このソースが、あなたのゲーム解析スキルアップに役立てば幸いです。