lernel32 を作ったとき参考にした書き込みをまとめておこうと思う
知ってる人は読み飛ばしてください
まず2chのスレから使えそうな書き込みをピックアップしてみた
アンパックに時間がかかりそうだったのでLERNEL32.dllで何とかする方向で。
GetLocalTimeとFileTimeToSystemTimeを2007/7/1 0:0:0.0を返す様にして、
LoadLibraryとGetModuleHandleがKERNEL32で呼び出されるのをLERNEL32に変更すればOK。
041期限解除のまとめ2
パッチ法: >>705 のとおり
ラッパ法:下記サイトのAPIフックの項を参考にする
ttp://ruffnex.oc.to/kenji/crackme/reverse_engineering.html
変更は次の3カ所
・GetLocalTime:上記サイトと同じ方法で
・GetModuleHandleA:GetModuleHandleA("lernel32"); を実行させる
・FindFirstFileA:INVALID_HANDLE_VALUE を返す
なお、VC++を持っていなければ2005 Express EditionとMicrosoft platform
SDKを↓に従ってインストールする
ttp://www.microsoft.com/japan/msdn/vstudio/express/visualc/usingpsdk/
とくに手順3をきちんとやらないと<windows.h>がないと怒られるので注意
2005 Express Editionを使用する場合、リバースエンジニアリングのサイト
にある仲介DLL生成補助ツールよりも↓を利用した方が良いかも知れない
ttp://www.chiyoclone.net/details.html#listexp
こちらを利用した場合はlernel32_dummy.cpp内の「( naked )」と「d_関数()」
の間に「void WINAPI」を挿入してくれ(1000個近くあるので一括置換しよう)
仲介DLL生成補助ツール上記のサイトの関数の置き換え方が参考になった
DLLの仲介を行い任意のAPIの動作を監視、もしくは変更する場合は、生成された.cppファイルを書きかえる必要があります。ここでは kernel32.dllの「GetSystemTime」APIの動作を変更する例を用います。まずはlernel32.cppを開きます。そしてコードの次の行を以下のように書きかえます。
//__declspec( naked ) void WINAPI d_GetSystemTime() { _asm{ jmp p_GetSystemTime } }
__declspec(dllexport) VOID WINAPI d_GetSystemTime(LPSYSTEMTIME t);
上の行をコメントアウトして、下の行を追加します。追加する場合はMSDNなどで、あらかじめAPIの定義(引数や戻り値など)を調べておいてください。kernel32.dllに実装されているGetSystemTimeと同じ引数、戻り値を持たなければなりません。
さらに、.cppファイルの最後に実際に動作させたいコードを追加します。
// .cppファイルの最後に追加
__declspec(dllexport) VOID WINAPI d_GetSystemTime(LPSYSTEMTIME t)
{
t->wYear = 1192;
t->wMonth = 5;
t->wDay = 15;
t->wDayOfWeek = 0;
t->wHour = 1;
t->wMinute = 1;
t->wSecond = 1;
t->wMilliseconds = 1000;
}
これで完了です。あとはVC++でビルドし、生成されたDLLが仲介DLLとなります。任意のEXEファイルと同じフォルダにコピーし、EXEファイルをバイナリエディタで開き、「KERNEL32.dll」の部分を「LERNEL32.dll」と変更してください。これによって、EXEファイルは kernel32.dllのAPIを呼び出すときに常に、仲介DLLを介してアクセスすることになります。
2chに書き込まれた書き換え例としてこれが参考になった
__declspec(dllexport) void WINAPI d_GetLocalTime(LPSYSTEMTIME t)
{
t->wYear = 2007;
t->wMonth = 7;
t->wDay = 31;
t->wDayOfWeek = 2;
t->wHour = 0;
t->wMinute = 0;
t->wSecond = 0;
t->wMilliseconds = 0;
}
__declspec(dllexport) HANDLE WINAPI d_FindFirstFileA(LPCTSTR n,LPWIN32_FIND_DATA d)
{
return INVALID_HANDLE_VALUE;
}
__declspec(dllexport) HMODULE WINAPI d_GetModuleHandleA(LPCTSTR s)
{
return GetModuleHandleA("lernel32");
}
こんなんでどうだろ?
voidから型は適当に変えてみた。
ビルド方法についてはこんな書き込みが参考になった
ひょっとしてVC++.NETでビルドする場合?某所の請け売りですが
「ファイル→新しい項目の追加」で新しくlerneldefファイルを作成し、そこに
listexportで作成したlernel32.defの内容をコピー
lernel.cppはそのままプロジェクトに追加
ビルド
だったりして。
とりあえず手っ取り早いのは
lernel.cppとlernel.defを適当なフォルダに置く
新規作成→既存のコードからプロジェクトを作成
プロジェクトファイルの場所:上のフォルダを指定
プロジェクトファイル名:lernel32
→次へ→DLLプロジェクトを選択→次へ→完了
プロジェクト→プロパティ
構成:Release
全般:文字セット:マルチバイト→適用
C/C++:コード生成:ランタイムライブラリ:マルチスレッド/MT→適用
リンカ:入力:モジュール定義ファイル:lernel32.def→適用
ビルド→構成マネージャ:Release→閉じる
ビルド→ソリューションのビルド
あくまでも1つの例なのであとは適宜変更してくれ
UnicodeとANSIに分けてコードを書く。
面倒ならUnicodeでなくMulti-Byte Character Setでビルドする。
Project→Properties→Linker→Inputで.defファイルを登録してね。
以上を参考にソースを書き換えビルドして解除に成功したわけですが
LoadLibraryではLERNLE32で呼ばれるようなので置き換えから外しました
VSのデバッガで時間の書き換え関数にブレークポイントをかけても
止まりませんでしたが、動作は正常に終了しました。
以上、試す場合は自己責任でよろしく
.