私たちは、必要な範囲で怠areなプログラマーであり、WinAPIおよび最新のWindows OSのアーキテクチャと調和するCを知っていると仮定します。 私たちは、ホイールを再発明することなく(そして腕と頭に負担をかけすぎないように)美しく、迅速かつ効率的にタスクを完了したいと考えています。
実験関数を探しましょう。 ntdll.dllには多くの利点があります。 私自身はWin7 64の下で書いていますが、素晴らしいライブラリの32ビット版を取りました。 念のため:%SystemDisk%\ Windows \ System32 \ ntdll.dll。
簡単にするために、Idaでntdllを開き、エクスポートされる関数を確認します。 Idaがない場合は、PEファイルで動作するプログラム(PEToolsなど)を使用できます。 Rtl(ランタイムライブラリ)プレフィックスを持つ関数に興味があります。 つまり、コードの実行中に、このシステム関数にサービスについて問い合わせることができます。
単純な関数を少し検索したところ、RtlComputeCrc32が見つかりました。
関数名をダブルクリックすると、逆アセンブルされたコードが表示されます。 HDasmやW32Dasmのような他の逆アセンブラーで関数を学習できます。 スペースを無駄にしないために、Idaデコンパイラーによって親切に提供された擬似コードRtlComputeCrc32を引用します(Hex-RaysデコンパイラーがEdit-> Pluginsプラグインで利用可能な場合、関数本体でF5を押します)。
すぐに多くの情報を取得します! 私たちが実際に探しているものを考えなければなりません。 必要なもの:
1)ntdllでアドレスを取得する関数の名前。
2)関数への正しいポインターを作成する関数のプロトタイプ。
3)正しい引数をそれに渡し、結果を正しく処理するための、おおよその作業原理。
擬似コードからすでに取得しているアイテム1-2。 ここでのタスクは、関数を理解し、それに基づいて何かからCRC32を計算するプログラムを作成することです。
関数がサイズがa3で、 a1がアルゴリズムの初期化値である配列a2のバイトを反復処理することは、擬似コードから簡単に理解できます。 バイトで計算を行った後、RtlCrc32Tableテーブルからインデックスを取得します(ダブルクリックすると、巨大なテーブルが表示されます)。 Google CRC32と実装例。すべてが正しいことを理解しています。
小さなことは、獲物を利用することです。 Visual Studioで空のコンソールアプリケーションを作成しましたが、もちろん他の環境でも実行できます。
GetModuleHandle()はntdllハンドルを返し、GetProcAddress()は関数のアドレスです。 UndocFoo型の関数へのポインターを使用して、RtlComputeCRC32()を呼び出します。
#include <stdio.h> #include <windows.h> typedef INT (WINAPI *UndocFoo)(INT accumCRC32, const BYTE* buffer, UINT buflen); int main() { HMODULE hDLL = GetModuleHandle(TEXT("ntdll.dll")); if (hDLL == NULL) { puts("[-] Failed to find ntdll.dll\n"); return EXIT_FAILURE; } puts("[+] Got ntdll.dll handle\n"); UndocFoo ComputeCrc32 = (UndocFoo)GetProcAddress(hDLL, "RtlComputeCrc32"); if (ComputeCrc32 == NULL) { puts("[-] Failed to find RtlComputeCrc32\n"); return EXIT_FAILURE; } puts("[+] Found RtlComputeCrc32 address\n"); puts("[*] Calling RtlComputeCrc32...\n"); BYTE buffer[] = {0x01, 'a', 7}; INT iCRC32 = ComputeCrc32(INT(0), (BYTE*)buffer, 3); printf("[+] Computed CRC32 --> 0x%x\n\n", iCRC32); puts("Press any key to quit\n"); getchar(); return EXIT_SUCCESS; }
成功。 任意のオンライン計算機を使用して確認できます。
バイト016107からCRC32 = 0x1c017c60が得られました。
オンライン計算機でも同じことがわかりました。
」
そのため、独自の機能を実装したり、他人の大きなコードを使用したりする時間を無駄にすることなく、このような素晴らしいプログラムを作成しました。 簡単で楽しかったです。