インラインアセンブラで特定の場所にコードを埋め込むときのアドレス調整
インラインアセンブラを使って、コードにパッチを当てるとき予め埋め込むアドレスが分かっていても call 文でアドレスを指定できないのが結構悩みどころだったりします。
『 call 目的アドレス - $ 』等の構文が使えればいいのですが、自アドレスに足し算はできても引き算で使うことはできません。
例えば、関数 function_test を埋め込むアドレスが 0x79123456 だとわかっている場合にそのAPI内部で使われている
0x79222222 で使われている function_api という関数を呼び出したい場合
こんな風に定義するとうまくいきます
#define BASE (function_test - 0x79123456 )
#define function_api 0x79222222 + BASE
後は関数内で call function_api と書いてコンパイルすれば自動的に適切な相対アドレスに変換されます
では実際にやってみます。
#define BASE (LogonUserWWW - 0x794E5f68) #define GetTokenInformation_ 0x7949DAAE + BASE #define GetLengthSid_ 0x79499AA4 +BASE #define AllocateLocallyUniqueId_ 0x7949680b + BASE #define memmove_ 0x794da5f4 + BASE //文字列定義 #define original_ 0x794e5f02 #define LsaConnectUntrusted_ 0x794e5f0c #define LsaLookupAuthenticationPackage_ 0x794e5f20 #define LsaDeregisterLogonProcess_ 0x794e5f40 #define LsaLogonUser_ 0x794e5f5a void __declspec(dllexport) __declspec(naked) WINAPI LogonUserWWW(){ |
定義はこんな感じ
794E5F02 db 'original',0 794E5F0B db '',0 794E5F0C db 'LsaConnectUntrusted',0 794E5F20 db 'LsaLookupAuthenticationPackage',0 794E5F3F db 00h; 794E5F40 db 'LsaDeregisterLogonProcess',0 794E5F5A db 'LsaLogonUser',0 794E5F67 db 00h; 794E5F68 db 00h; <- コードを埋め込みたい場所 794E5F69 db 00h; 794E5F6A db 00h; |
埋め込み先はこんな感じ
L794E6024: push ebx push esi xor esi,esi cmp [ebp+20h],esi jz L794E6094 lea eax,[ebp+2Ch] call GetTokenInformation push eax push esi push esi push 00000001h push [ebp-08h] mov [ebp+2Ch],esi call ebx cmp [ebp+2Ch],esi jz L794E6094 push edi mov edi,[KERNEL32.dll!LocalAlloc] push [ebp+2Ch] push 00000040h call GetTokenInformation mov esi,eax lea eax,[ebp+2Ch] |
うまいこと変換できました・ω・
Comments