← All Articles

IDA ProでWin32API実行失敗時のエラーを取得する

Posted on

LastError表示画面

IDA Proを使ってバイナリ解析を行っていると、Win32APIが失敗した理由を確認したくなる時ってありますよね。

CreateRemoteThread();のようなWinAPI32関数は実行失敗時には0を返し、失敗の理由はGetLastError();を呼び出すことで確認ができます。

ただ、マルウェア等のプログラムでは関数の呼び出し失敗時に丁寧にGetLastError();が呼ばれる仕様になっていないことが多いため、エラーの理由が分からないときもあります。

そんなとき、以下のIDAPythonで簡単にGetLastError()を呼び出してエラーを確認することができます。


GetLastError()呼び出しIDAPythonスクリプト


Hex blog記事よりPythonのコードを引用しました。

GetLastError()呼び出し
getlasterror = Appcall.proto("kernel32_GetLastError", "DWORD __stdcall GetLastError();")
print "lasterror=", getlasterror()

これをIDA Pro画面最下部にて実行すると下記の様にlasterrorが5であることが確認できます。

IDAPython実行画面

MSDNでエラーコード5が ERROR_ACCESS_DENIED であることを確認できます。

https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes—0-499-


ValueError: Could not parse typeエラー回避


解析のタイミングによっては、上記Pythonスクリプト実行時にValueError: Could not parse typeが返りLastErrorが取得できない場合があると思います。

これは、DWORDの型をIDAPythonでパース出来ていないことが理由であろうと思います。

Appcallエラー
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Program Files\IDA Pro 7.3\python\ida_idd.py", line 2007, in proto
    tif = Appcall__.__typedecl_or_tinfo(proto_or_tinfo, flags)
  File "C:\Program Files\IDA Pro 7.3\python\ida_idd.py", line 1984, in __typedecl_or_tinfo
    raise ValueError, "Could not parse type: " + typedecl_or_tinfo
ValueError: Could not parse type: DWORD __stdcall GetLastError();

以下の様に、元のスクリプトのDWORDをunsigned longに書き換えてあげると、エラーなしでLastErrorを取得することが出来ます。

エラー回避版GetLastError()呼び出し
getlasterror = Appcall.proto("kernel32_GetLastError", "unsigned long __stdcall GetLastError();")
print "lasterror=", getlasterror()
reversingidapythonida pro