5ちゃんねるの総力を挙げて、人力でアセンブリや機械語を逆コンパイルするスレッドです。コード解析の達人やヒマ人の皆様、ご協力下さい。
===依頼テンプレここから===
【依頼の目的と内容説明】ここに目的と説明を書く
【プロセッサの種類】x86/x64/ARM/JVM など
【OSの種類】Windows/Linux/Mac/Android/iOS など
【言語】C/C++/Java/C# など
【報酬金額と送金方法】報酬なし/銀行振込/WebMoney など
【アセンブリまたは機械語】以下にアセンブリまたは機械語を記載
===依頼テンプレここまで===
依頼は一度に1関数までとします。あまりにも長いコードは人力では逆コンパイルできません。常識の範囲でご利用ください。
探検
アセンブリや機械語を解析して楽しむスレ
■ このスレッドは過去ログ倉庫に格納されています
2021/06/19(土) 17:16:50.94ID:KpP01EPy
2021/06/25(金) 23:03:34.71ID:W5hhXd/9
>>63
NtUserSetImeHotKey関数をシステムコール経由で呼んでいるらしい。
https://reactos.org/wiki/Techwiki:Win32k/syscalls
これ以上のことは分からない。
NtUserSetImeHotKey関数をシステムコール経由で呼んでいるらしい。
https://reactos.org/wiki/Techwiki:Win32k/syscalls
これ以上のことは分からない。
2021/06/26(土) 23:13:53.65ID:RPMP544+
こっちでまとめてます。秘密基地です。
https://github.com/katahiromz/secret_base
https://github.com/katahiromz/secret_base
2021/06/29(火) 20:06:52.90ID:+6dhbc6a
```asm
neg eax
sbb eax, eax
```
[=>]
```txt
CarryFlag = (eax != 0);
eax = -(LONG)eax;
eax -= eax + CarryFlag;
```
Devide the cases about CarryFlag and we get:
```c-like
if (eax != 0)
eax = 0xFFFFFFFF;
else
eax = 0;
```
これがneg-sbbのトリック。
neg eax
sbb eax, eax
```
[=>]
```txt
CarryFlag = (eax != 0);
eax = -(LONG)eax;
eax -= eax + CarryFlag;
```
Devide the cases about CarryFlag and we get:
```c-like
if (eax != 0)
eax = 0xFFFFFFFF;
else
eax = 0;
```
これがneg-sbbのトリック。
2021/07/13(火) 10:27:53.03ID:M2x6Ny3W
riscはオナニーしながらでも読めるにゃ
2021/07/13(火) 11:39:35.80ID:EvOOyjG8
はやっ
2021/07/14(水) 01:35:31.92ID:lv8+vNga
>>66
```asm
neg eax
sbb eax, eax
```
これにさらに「inc eax」が付くとこうなる:
```asm
neg eax
sbb eax, eax
inc eax
```
[=>]
```c
if (eax != 0) eax = 0;
else eax = 1;
```
つまり、eaxの論理否定となる。
```asm
neg eax
sbb eax, eax
```
これにさらに「inc eax」が付くとこうなる:
```asm
neg eax
sbb eax, eax
inc eax
```
[=>]
```c
if (eax != 0) eax = 0;
else eax = 1;
```
つまり、eaxの論理否定となる。
2021/08/03(火) 21:07:31.90ID:Q9+5cbUY
```txt
Label_YYYY:
...
if (exp) goto Label_YYYY;
```
のような場合は
```txt
do
...
if (exp) goto Label_YYYY;
```
```txt
if (exp) goto Label_XXXX;
...
Label_XXXX:
...
```
のような並びがあるときは、
```txt
if (!(exp)) {
...
}
...
```
に書き換えることができる。
Label_YYYY:
...
if (exp) goto Label_YYYY;
```
のような場合は
```txt
do
...
if (exp) goto Label_YYYY;
```
```txt
if (exp) goto Label_XXXX;
...
Label_XXXX:
...
```
のような並びがあるときは、
```txt
if (!(exp)) {
...
}
...
```
に書き換えることができる。
2021/08/03(火) 21:09:13.31ID:Q9+5cbUY
>>70は書き損じだから無視して。
```txt
Label_YYYY:
...
if (exp) goto Label_YYYY;
```
は、
```txt
do
...
} while (exp);
```
に置き換えることができる。
```txt
if (exp) goto Label_XXXX;
...
Label_XXXX:
...
```
は、
```txt
if (!(exp)) {
...
}
...
```
に書き換えることができる。
```txt
Label_YYYY:
...
if (exp) goto Label_YYYY;
```
は、
```txt
do
...
} while (exp);
```
に置き換えることができる。
```txt
if (exp) goto Label_XXXX;
...
Label_XXXX:
...
```
は、
```txt
if (!(exp)) {
...
}
...
```
に書き換えることができる。
2021/08/03(火) 21:16:45.35ID:Q9+5cbUY
ジャンプ命令は基本的にgoto文に置き換えることができる。
ジャンプ命令の符号あり符号なしの区別は
http://www.unixwiz.net/techtips/x86-jumps.html
にまとまっている。例えば、JA命令はJump if aboveだからunsignedであり、JL命令はJump if lessだからsignedである。
```asm
cmp X, Y
ja Label_ZZZZ
```
の場合は、
```txt
if ((unsigned)X > (unsigned)Y) goto Label_ZZZZ;
```
と書き換えることができる。
「test X, Y」はXとYのビット論理積の結果によってフラグを更新する。
例えば
```asm
test eax, eax
jz Label_XXXX
```
は
```txt
if (eax == 0) goto Label_XXXX;
```
に置き換え可能。
ジャンプ命令の符号あり符号なしの区別は
http://www.unixwiz.net/techtips/x86-jumps.html
にまとまっている。例えば、JA命令はJump if aboveだからunsignedであり、JL命令はJump if lessだからsignedである。
```asm
cmp X, Y
ja Label_ZZZZ
```
の場合は、
```txt
if ((unsigned)X > (unsigned)Y) goto Label_ZZZZ;
```
と書き換えることができる。
「test X, Y」はXとYのビット論理積の結果によってフラグを更新する。
例えば
```asm
test eax, eax
jz Label_XXXX
```
は
```txt
if (eax == 0) goto Label_XXXX;
```
に置き換え可能。
2021/08/04(水) 15:25:34.02ID:YCRiyQzz
if (exp)
2021/08/04(水) 15:26:28.93ID:YCRiyQzz
```txt
if (exp)
{
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp)
{
...
}
else
...
Label_XXXX:
```
if (exp)
{
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp)
{
...
}
else
...
Label_XXXX:
```
2021/08/04(水) 15:27:12.21ID:YCRiyQzz
```txt
if (exp) {
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp) {
...
} else {
...
}
Label_XXXX:
```
に置き換え可能。
if (exp) {
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp) {
...
} else {
...
}
Label_XXXX:
```
に置き換え可能。
2021/08/13(金) 14:20:39.59ID:xGO78+x4
ImmAssociateContext
ImmAssociateContextEx
ImmConfigureIMEA/W
ImmEscapeA/W
Imm32GetClientImcCache
ImmGetCompositionStringA/W
ImmGetContext
ImmInstallIMEW
ImmIsUIMessageA/W
ImmRequestMessageA/W
ImmSetCompositionStringA/W
ImmGetImeMenuItemsA/W
ImmLockIMC
ImmGenerateMessage
ImmTranslateMessage
ImmProcessKey
ImmSetActiveContext
宿題がまだこ〜んなにあるぜ。本当に全部できるのかよ。
ImmAssociateContextEx
ImmConfigureIMEA/W
ImmEscapeA/W
Imm32GetClientImcCache
ImmGetCompositionStringA/W
ImmGetContext
ImmInstallIMEW
ImmIsUIMessageA/W
ImmRequestMessageA/W
ImmSetCompositionStringA/W
ImmGetImeMenuItemsA/W
ImmLockIMC
ImmGenerateMessage
ImmTranslateMessage
ImmProcessKey
ImmSetActiveContext
宿題がまだこ〜んなにあるぜ。本当に全部できるのかよ。
2021/09/24(金) 02:14:10.10ID:i//SzVJC
まあ、これを見て実際の逆工学をやってみるもよし
https://github.com/katahiromz/DecodersTatami/blob/main/target/analysis/Func00401550.txt
セキュリティエンジニアの道ははるかに遠い
https://github.com/katahiromz/DecodersTatami/blob/main/target/analysis/Func00401550.txt
セキュリティエンジニアの道ははるかに遠い
2021/09/25(土) 20:48:50.24ID:H+l7h9ZE
とりあえず、x86 CPUについて復習しようね。
eax, ebx, ecx, edx。
この4つは汎用レジスタで、それぞれ32ビット整数。
esp, ebp。
この二つは特にスタックに使われるレジスタ。
eaxの中には16ビット整数のaxがある。axはeaxの下位16ビット整数。
ebxの中には16ビット整数のbxがある。bxはebxの下位16ビット整数。
ecxの中には16ビット整数のcxがある。cxはecxの下位16ビット整数。
edxの中には16ビット整数のdxがある。dxはedxの下位16ビット整数。
eax, ebx, ecx, edx。
この4つは汎用レジスタで、それぞれ32ビット整数。
esp, ebp。
この二つは特にスタックに使われるレジスタ。
eaxの中には16ビット整数のaxがある。axはeaxの下位16ビット整数。
ebxの中には16ビット整数のbxがある。bxはebxの下位16ビット整数。
ecxの中には16ビット整数のcxがある。cxはecxの下位16ビット整数。
edxの中には16ビット整数のdxがある。dxはedxの下位16ビット整数。
2021/09/25(土) 20:52:28.04ID:H+l7h9ZE
axはalとahの2つに分かれている。alはaxの下位8ビットで、ahはaxの上位8ビット。
bxはblとbhの2つに分かれている。blはbxの下位8ビットで、bhはbxの上位8ビット。
cxはclとchの2つに分かれている。clはcxの下位8ビットで、chはcxの上位8ビット。
dxはdlとdhの2つに分かれている。dlはdxの下位8ビットで、dhはdxの上位8ビット。
esi, edi。
この2つのレジスタは、メモリーの転送によく使われる。
esiのなかには16ビット整数のsiがある。siはesiの下位16ビット整数。
ediのなかには16ビット整数のdiがある。diはediの下位16ビット整数。
esiのsはsourceで、ediのdはdestinationだ。
bxはblとbhの2つに分かれている。blはbxの下位8ビットで、bhはbxの上位8ビット。
cxはclとchの2つに分かれている。clはcxの下位8ビットで、chはcxの上位8ビット。
dxはdlとdhの2つに分かれている。dlはdxの下位8ビットで、dhはdxの上位8ビット。
esi, edi。
この2つのレジスタは、メモリーの転送によく使われる。
esiのなかには16ビット整数のsiがある。siはesiの下位16ビット整数。
ediのなかには16ビット整数のdiがある。diはediの下位16ビット整数。
esiのsはsourceで、ediのdはdestinationだ。
2021/09/25(土) 21:08:38.10ID:+1RCibwo
eaxの中にaxレジスタがあり、axレジスタの中にal, ahレジスタがあるという見方もできる。このような構造になっているのは16ビットとの互換性のためである。
64ビットCPUのx64、別名amd64ではrax, rbx, rcx, rdxというように、頭にrが付いた64ビットレジスタが増設された。逆工学の主な戦場はまだ32ビットにあるが、今後64ビットを対応しないといけない。
64ビットCPUのx64、別名amd64ではrax, rbx, rcx, rdxというように、頭にrが付いた64ビットレジスタが増設された。逆工学の主な戦場はまだ32ビットにあるが、今後64ビットを対応しないといけない。
2021/09/28(火) 20:27:04.96ID:m9n91EHz
【問題】
```asm
push 0x30
mov edi, eax
pop ecx
```
【解読】
まず、
`push 0x30`と`mov edi, eax`は独立しているので交換可能。
```asm
mov edi, eax
push 0x30
pop ecx
```
さらに`push 0x30`と`pop ecx`が並んでいるので、これは`ecx = 0x30;`と解釈できる。
よって
```asm
push 0x30
mov edi, eax
pop ecx
```
[=>]
```asm
push 0x30
mov edi, eax
pop ecx
```
【解読】
まず、
`push 0x30`と`mov edi, eax`は独立しているので交換可能。
```asm
mov edi, eax
push 0x30
pop ecx
```
さらに`push 0x30`と`pop ecx`が並んでいるので、これは`ecx = 0x30;`と解釈できる。
よって
```asm
push 0x30
mov edi, eax
pop ecx
```
[=>]
2021/09/28(火) 20:29:43.46ID:m9n91EHz
```txt
edi = eax;
ecx = 0x30;
```
である。□
```asm
push (即値)
pop (レジスタX)
```
[=>]
```txt
(レジスタX) = (即値);
```
はpush-popトリックだから覚えておいてね。
edi = eax;
ecx = 0x30;
```
である。□
```asm
push (即値)
pop (レジスタX)
```
[=>]
```txt
(レジスタX) = (即値);
```
はpush-popトリックだから覚えておいてね。
2022/01/17(月) 19:44:42.22ID:32ay/bkz
今回は、Win32 FileID APIs 1.1の解読をします。
duck.com で「FileID APIs 1.1」を検索し、FileID APIs 1.1をこっそりダウンロード。
最適化なしで、次のソースをビルドします。
#define _WIN32_WINNT 0x400
#include <windows.h>
#include "fileextd.h"
int main(void)
{
SetFileInformationByHandle((HANDLE)0xDEADFACE, FileBasicInfo, NULL, 0);
GetFileInformationByHandleEx((HANDLE)0xDEADFACE, FileBasicInfo, NULL, 0);
OpenFileById((HANDLE)0xDEADFACE, NULL, 0, 0, NULL, 0);
return 0;
}
これをDecodersTatamiに掛けてdeadfaceをgrep検索します。
duck.com で「FileID APIs 1.1」を検索し、FileID APIs 1.1をこっそりダウンロード。
最適化なしで、次のソースをビルドします。
#define _WIN32_WINNT 0x400
#include <windows.h>
#include "fileextd.h"
int main(void)
{
SetFileInformationByHandle((HANDLE)0xDEADFACE, FileBasicInfo, NULL, 0);
GetFileInformationByHandleEx((HANDLE)0xDEADFACE, FileBasicInfo, NULL, 0);
OpenFileById((HANDLE)0xDEADFACE, NULL, 0, 0, NULL, 0);
return 0;
}
これをDecodersTatamiに掛けてdeadfaceをgrep検索します。
2022/01/17(月) 19:45:19.85ID:32ay/bkz
これをDecodersTatamiに掛けてdeadfaceをgrep検索します。
main関数が見つかります。呼び出しツリーは以下のようになります。
main
...→ Func00401341 // SetFileInformationByHandle
......→ Func0040105F
......→ Func004010B9
...→ Func0040122D // GetFileInformationByHandleEx
......→ Func00401032
......→ Func004010B9
...→ Func004010D7 // OpenFileById
......→ Func004010B9
というわけで、最初にFunc004010B9を解読します。
main関数が見つかります。呼び出しツリーは以下のようになります。
main
...→ Func00401341 // SetFileInformationByHandle
......→ Func0040105F
......→ Func004010B9
...→ Func0040122D // GetFileInformationByHandleEx
......→ Func00401032
......→ Func004010B9
...→ Func004010D7 // OpenFileById
......→ Func004010B9
というわけで、最初にFunc004010B9を解読します。
2022/01/17(月) 19:46:57.43ID:32ay/bkz
【依頼の目的と内容説明】Win32 FileID APIs 1.1
【プロセッサの種類】x86
【OSの種類】Windows
【言語】C/C++
【報酬金額と送金方法】報酬なし
【アセンブリまたは機械語】
```asm
proc Func004010B9@4 Label_004010B9
attrs [[stdcall]]
# call_from : 004010D7 0040122D 00401341
# call_to : 0040108C
Label_004010B9:
004010B9: 8B FF : mov edi, edi
004010BB: 55 : push ebp
004010BC: 8B EC : mov ebp, esp
004010BE: 56 : push esi
004010BF: FF 75 08 : push dword [ebp+0x8]
004010C2: E8 C5 FF FF FF : call Func0040108C@4
004010C7: 8B F0 : mov esi, eax
004010C9: 56 : push esi
004010CA: FF 15 08 80 40 00 : call kernel32.dll!SetLastError
004010D0: 8B C6 : mov eax, esi
004010D2: 5E : pop esi
004010D3: 5D : pop ebp
004010D4: C2 04 00 : ret 0x4
end proc
```
【プロセッサの種類】x86
【OSの種類】Windows
【言語】C/C++
【報酬金額と送金方法】報酬なし
【アセンブリまたは機械語】
```asm
proc Func004010B9@4 Label_004010B9
attrs [[stdcall]]
# call_from : 004010D7 0040122D 00401341
# call_to : 0040108C
Label_004010B9:
004010B9: 8B FF : mov edi, edi
004010BB: 55 : push ebp
004010BC: 8B EC : mov ebp, esp
004010BE: 56 : push esi
004010BF: FF 75 08 : push dword [ebp+0x8]
004010C2: E8 C5 FF FF FF : call Func0040108C@4
004010C7: 8B F0 : mov esi, eax
004010C9: 56 : push esi
004010CA: FF 15 08 80 40 00 : call kernel32.dll!SetLastError
004010D0: 8B C6 : mov eax, esi
004010D2: 5E : pop esi
004010D3: 5D : pop ebp
004010D4: C2 04 00 : ret 0x4
end proc
```
2022/01/17(月) 19:50:05.81ID:32ay/bkz
これは非常に簡単だ。
```txt
UNKNOWN Func004010B9(UNKNOWN ARGV[1])
{
Push esi;
esi = eax = Func0040108C(ARGV[1]);
SetLastError(esi);
eax = esi;
Pop esi;
return eax;
}
```
単純化して
```txt
DWORD Func004010B9(UNKNOWN ARGV[1])
{
DWORD dwError = Func0040108C(ARGV[1]);
SetLastError(dwError);
return dwError;
}
```
```txt
UNKNOWN Func004010B9(UNKNOWN ARGV[1])
{
Push esi;
esi = eax = Func0040108C(ARGV[1]);
SetLastError(esi);
eax = esi;
Pop esi;
return eax;
}
```
単純化して
```txt
DWORD Func004010B9(UNKNOWN ARGV[1])
{
DWORD dwError = Func0040108C(ARGV[1]);
SetLastError(dwError);
return dwError;
}
```
2022/01/17(月) 19:53:15.58ID:32ay/bkz
おそらくFunc0040108Cはエラーコードを返す。
また、typeof(Func004010B9.ARGV[1]) == typeof(Func0040108C.ARGV[1])であることがわかる。
ではFunc0040108Cを見てみよう。
```asm
proc Func0040108C Label_0040108C
attrs [[noreturn]]
# call_from : 004010B9
# jump_to : 004010B6
Label_0040108C:
0040108C: 8B FF : mov edi, edi
0040108E: 55 : push ebp
0040108F: 8B EC : mov ebp, esp
00401091: A1 B0 DD 40 00 : mov eax, [0x40ddb0]
00401096: 85 C0 : test eax, eax
00401098: 75 1C : jnz Label_004010B6
0040109A: 68 58 81 40 00 : push 0x408158
0040109F: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
004010A5: 68 AC 81 40 00 : push 0x4081ac
004010AA: 50 : push eax
004010AB: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
004010B1: A3 B0 DD 40 00 : mov [0x40ddb0], eax
Label_004010B6:
004010B6: 5D : pop ebp # jump_from : 00401098
004010B7: FF E0 : jmp eax
end proc
```asm
また、typeof(Func004010B9.ARGV[1]) == typeof(Func0040108C.ARGV[1])であることがわかる。
ではFunc0040108Cを見てみよう。
```asm
proc Func0040108C Label_0040108C
attrs [[noreturn]]
# call_from : 004010B9
# jump_to : 004010B6
Label_0040108C:
0040108C: 8B FF : mov edi, edi
0040108E: 55 : push ebp
0040108F: 8B EC : mov ebp, esp
00401091: A1 B0 DD 40 00 : mov eax, [0x40ddb0]
00401096: 85 C0 : test eax, eax
00401098: 75 1C : jnz Label_004010B6
0040109A: 68 58 81 40 00 : push 0x408158
0040109F: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
004010A5: 68 AC 81 40 00 : push 0x4081ac
004010AA: 50 : push eax
004010AB: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
004010B1: A3 B0 DD 40 00 : mov [0x40ddb0], eax
Label_004010B6:
004010B6: 5D : pop ebp # jump_from : 00401098
004010B7: FF E0 : jmp eax
end proc
```asm
2022/01/17(月) 20:00:34.53ID:32ay/bkz
解読する。
```asm
DWORD Func0040108C(UNKNOWN ARGV[1])
{
eax = [0x40ddb0];
if (eax) goto Label_004010B6;
eax = GetModuleHandleA(0x408158);
[0x40ddb0] = eax = GetProcAddress(eax, 0x4081ac);
Label_004010B6:
return eax;
}
```
[0x40ddb0]はおそらく関数ポインタのキャッシュだ。
0x408158と0x4081acはANSI文字列である。
decode.pyのCR2_OPTIONSに--read ...を追加して再デコード:
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32']
```
```asm
DWORD Func0040108C(UNKNOWN ARGV[1])
{
eax = [0x40ddb0];
if (eax) goto Label_004010B6;
eax = GetModuleHandleA(0x408158);
[0x40ddb0] = eax = GetProcAddress(eax, 0x4081ac);
Label_004010B6:
return eax;
}
```
[0x40ddb0]はおそらく関数ポインタのキャッシュだ。
0x408158と0x4081acはANSI文字列である。
decode.pyのCR2_OPTIONSに--read ...を追加して再デコード:
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32']
```
2022/01/17(月) 20:05:56.89ID:32ay/bkz
次の結果が得られる。
```txt
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408158 4E 54 44 4C 4C 2E 44 4C 4C 00 00 00 4E 74 51 75 NTDLL.DLL NtQu
00408168 65 72 79 49 6E 66 6F 72 6D 61 74 69 6F 6E 46 69 eryInformationFi
32 (0x20) bytes read.
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
004081AC 52 74 6C 4E 74 53 74 61 74 75 73 54 6F 44 6F 73 RtlNtStatusToDos
004081BC 45 72 72 6F 72 00 00 00 00 00 00 00 05 00 00 C0 Error . .
32 (0x20) bytes read.
```
0x408158は「NTDLL.DLL」であり、0x4081acは「RtlNtStatusToDosError」である。
RtlNtStatusToDosErrorのプロトタイプは、検索して調べると
ULONG RtlNtStatusToDosError(NTSTATUS Status);
である。
```txt
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408158 4E 54 44 4C 4C 2E 44 4C 4C 00 00 00 4E 74 51 75 NTDLL.DLL NtQu
00408168 65 72 79 49 6E 66 6F 72 6D 61 74 69 6F 6E 46 69 eryInformationFi
32 (0x20) bytes read.
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
004081AC 52 74 6C 4E 74 53 74 61 74 75 73 54 6F 44 6F 73 RtlNtStatusToDos
004081BC 45 72 72 6F 72 00 00 00 00 00 00 00 05 00 00 C0 Error . .
32 (0x20) bytes read.
```
0x408158は「NTDLL.DLL」であり、0x4081acは「RtlNtStatusToDosError」である。
RtlNtStatusToDosErrorのプロトタイプは、検索して調べると
ULONG RtlNtStatusToDosError(NTSTATUS Status);
である。
2022/01/17(月) 20:06:48.16ID:32ay/bkz
よって整理すると
```txt
typedef ULONG (APIENTRY* FN_RtlNtStatusToDosError)(NTSTATUS);
FN_RtlNtStatusToDosError g_pRtlNtStatusToDosError = NULL;
DWORD Func0040108C(NTSTATUS Status)
{
if (!g_pRtlNtStatusToDosError)
g_pRtlNtStatusToDosError = (FN_RtlNtStatusToDosError)
GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "RtlNtStatusToDosError");
return g_pRtlNtStatusToDosError(Status);
}
```
□
続きはまた明日。
```txt
typedef ULONG (APIENTRY* FN_RtlNtStatusToDosError)(NTSTATUS);
FN_RtlNtStatusToDosError g_pRtlNtStatusToDosError = NULL;
DWORD Func0040108C(NTSTATUS Status)
{
if (!g_pRtlNtStatusToDosError)
g_pRtlNtStatusToDosError = (FN_RtlNtStatusToDosError)
GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "RtlNtStatusToDosError");
return g_pRtlNtStatusToDosError(Status);
}
```
□
続きはまた明日。
2022/01/18(火) 10:34:45.36ID:kpMFjbVI
typeof(Func004010B9.ARGV[1]) == NTSTATUSであることがわかった。最初、
004010B7: FF E0 : jmp eax
のところがよくわからなかったが、スタックフレームなしに関数ポインタに直接飛んでいることがわかった。
これをnoreturn-jmpトリックと呼ぶことにする。
次はFunc0040105F:
```asm
proc Func0040105F Label_0040105F
attrs [[noreturn]]
# call_from : 00401341
# jump_to : 00401089
Label_0040105F:
0040105F: 8B FF : mov edi, edi
00401061: 55 : push ebp
00401062: 8B EC : mov ebp, esp
00401064: A1 A8 DD 40 00 : mov eax, [0x40dda8]
00401069: 85 C0 : test eax, eax
0040106B: 75 1C : jnz Label_00401089
0040106D: 68 58 81 40 00 : push 0x408158
00401072: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
00401078: 68 7C 81 40 00 : push 0x40817c
0040107D: 50 : push eax
0040107E: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
00401084: A3 A8 DD 40 00 : mov [0x40dda8], eax
Label_00401089:
00401089: 5D : pop ebp # jump_from : 0040106B
0040108A: FF E0 : jmp eax
end proc
```
004010B7: FF E0 : jmp eax
のところがよくわからなかったが、スタックフレームなしに関数ポインタに直接飛んでいることがわかった。
これをnoreturn-jmpトリックと呼ぶことにする。
次はFunc0040105F:
```asm
proc Func0040105F Label_0040105F
attrs [[noreturn]]
# call_from : 00401341
# jump_to : 00401089
Label_0040105F:
0040105F: 8B FF : mov edi, edi
00401061: 55 : push ebp
00401062: 8B EC : mov ebp, esp
00401064: A1 A8 DD 40 00 : mov eax, [0x40dda8]
00401069: 85 C0 : test eax, eax
0040106B: 75 1C : jnz Label_00401089
0040106D: 68 58 81 40 00 : push 0x408158
00401072: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
00401078: 68 7C 81 40 00 : push 0x40817c
0040107D: 50 : push eax
0040107E: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
00401084: A3 A8 DD 40 00 : mov [0x40dda8], eax
Label_00401089:
00401089: 5D : pop ebp # jump_from : 0040106B
0040108A: FF E0 : jmp eax
end proc
```
2022/01/18(火) 10:36:01.65ID:kpMFjbVI
これもnoreturn-jmpトリックのようだ。とりあえず、decode.pyのCR2_OPTIONSに--read ...を追加して再デコード:
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32', '--read', '0x408158', '32', '--read', '0x40817c', '32']
```
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408158 4E 54 44 4C 4C 2E 44 4C 4C 00 00 00 4E 74 51 75 NTDLL.DLL NtQu
00408168 65 72 79 49 6E 66 6F 72 6D 61 74 69 6F 6E 46 69 eryInformationFi
32 (0x20) bytes read.
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
0040817C 4E 74 53 65 74 49 6E 66 6F 72 6D 61 74 69 6F 6E NtSetInformation
0040818C 46 69 6C 65 00 00 00 00 4E 74 51 75 65 72 79 44 File NtQueryD
32 (0x20) bytes read.
「NTDLL.DLL」と「NtSetInformationFile」が得られた。NtSetInformationFileのプロトタイプは
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32', '--read', '0x408158', '32', '--read', '0x40817c', '32']
```
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408158 4E 54 44 4C 4C 2E 44 4C 4C 00 00 00 4E 74 51 75 NTDLL.DLL NtQu
00408168 65 72 79 49 6E 66 6F 72 6D 61 74 69 6F 6E 46 69 eryInformationFi
32 (0x20) bytes read.
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
0040817C 4E 74 53 65 74 49 6E 66 6F 72 6D 61 74 69 6F 6E NtSetInformation
0040818C 46 69 6C 65 00 00 00 00 4E 74 51 75 65 72 79 44 File NtQueryD
32 (0x20) bytes read.
「NTDLL.DLL」と「NtSetInformationFile」が得られた。NtSetInformationFileのプロトタイプは
2022/01/18(火) 10:36:31.35ID:kpMFjbVI
NTSTATUS NtSetInformationFile(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
であるから、
typdef NTSTATUS (APIENTRY *FN_NtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
FN_NtSetInformationFile g_pNtSetInformationFile = NULL;
NTSTATUS APIENTRY Func0040105F(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{
if (!g_pNtSetInformationFile)
g_pNtSetInformationFile = GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtSetInformationFile");
return (*g_pNtSetInformationFile)(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
□
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
であるから、
typdef NTSTATUS (APIENTRY *FN_NtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
FN_NtSetInformationFile g_pNtSetInformationFile = NULL;
NTSTATUS APIENTRY Func0040105F(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{
if (!g_pNtSetInformationFile)
g_pNtSetInformationFile = GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtSetInformationFile");
return (*g_pNtSetInformationFile)(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
□
2022/01/18(火) 10:45:00.41ID:kpMFjbVI
次はFunc00401032。
```asm
proc Func00401032 Label_00401032
attrs [[noreturn]]
# call_from : 0040122D
# jump_to : 0040105C
Label_00401032:
00401032: 8B FF : mov edi, edi
00401034: 55 : push ebp
00401035: 8B EC : mov ebp, esp
00401037: A1 A4 DD 40 00 : mov eax, [0x40dda4]
0040103C: 85 C0 : test eax, eax
0040103E: 75 1C : jnz Label_0040105C
00401040: 68 58 81 40 00 : push 0x408158
00401045: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
0040104B: 68 64 81 40 00 : push 0x408164
00401050: 50 : push eax
00401051: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
00401057: A3 A4 DD 40 00 : mov [0x40dda4], eax
Label_0040105C:
0040105C: 5D : pop ebp # jump_from : 0040103E
0040105D: FF E0 : jmp eax
end proc
```
これもnoreturn-jmpトリック。
```asm
proc Func00401032 Label_00401032
attrs [[noreturn]]
# call_from : 0040122D
# jump_to : 0040105C
Label_00401032:
00401032: 8B FF : mov edi, edi
00401034: 55 : push ebp
00401035: 8B EC : mov ebp, esp
00401037: A1 A4 DD 40 00 : mov eax, [0x40dda4]
0040103C: 85 C0 : test eax, eax
0040103E: 75 1C : jnz Label_0040105C
00401040: 68 58 81 40 00 : push 0x408158
00401045: FF 15 04 80 40 00 : call kernel32.dll!GetModuleHandleA
0040104B: 68 64 81 40 00 : push 0x408164
00401050: 50 : push eax
00401051: FF 15 00 80 40 00 : call kernel32.dll!GetProcAddress
00401057: A3 A4 DD 40 00 : mov [0x40dda4], eax
Label_0040105C:
0040105C: 5D : pop ebp # jump_from : 0040103E
0040105D: FF E0 : jmp eax
end proc
```
これもnoreturn-jmpトリック。
2022/01/18(火) 10:45:21.84ID:kpMFjbVI
decode.pyのCR2_OPTIONSに--read ...を追加して再デコード:
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32', '--read', '0x408158', '32', '--read', '0x40817c', '32', '--read', '0x408164', '32']
```
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408164 4E 74 51 75 65 72 79 49 6E 66 6F 72 6D 61 74 69 NtQueryInformati
00408174 6F 6E 46 69 6C 65 00 00 4E 74 53 65 74 49 6E 66 onFile NtSetInf
32 (0x20) bytes read.
NtQueryInformationFileのプロトタイプは
NTSTATUS NtQueryInformationFile(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
であるから、
```python
CR2_OPTIONS = ['--addr', '--hex', '--read', '0x408158', '32', '--read', '0x4081ac', '32', '--read', '0x408158', '32', '--read', '0x40817c', '32', '--read', '0x408164', '32']
```
## Read Memory ##
+ADDRESS +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00408164 4E 74 51 75 65 72 79 49 6E 66 6F 72 6D 61 74 69 NtQueryInformati
00408174 6F 6E 46 69 6C 65 00 00 4E 74 53 65 74 49 6E 66 onFile NtSetInf
32 (0x20) bytes read.
NtQueryInformationFileのプロトタイプは
NTSTATUS NtQueryInformationFile(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
であるから、
2022/01/18(火) 10:45:51.37ID:kpMFjbVI
typdef NTSTATUS (APIENTRY *FN_NtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
FN_NtQueryInformationFile g_pNtQueryInformationFile = NULL;
NTSTATUS Func00401032(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{
if (!g_pNtQueryInformationFile)
g_pNtQueryInformationFile = (FN_NtQueryInformationFile)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryInformationFile");
retuern (*g_pNtQueryInformationFile)(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
□
続きは明日やろう。
FN_NtQueryInformationFile g_pNtQueryInformationFile = NULL;
NTSTATUS Func00401032(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{
if (!g_pNtQueryInformationFile)
g_pNtQueryInformationFile = (FN_NtQueryInformationFile)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryInformationFile");
retuern (*g_pNtQueryInformationFile)(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
□
続きは明日やろう。
97デフォルトの名無しさん
2022/11/28(月) 18:36:01.95ID:QIQXhRT5 明日は来ない
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【野球】大谷翔平、佐々木朗希、山本由伸らがWBC辞退なら広がる不協和音… 『過去イチ盛り上がらない大会』になる可能性も★2 [冬月記者★]
- 【国際】ロシアはすでに戦争準備段階――ポーランド軍トップが警告 [ぐれ★]
- 【news23】小川彩佳アナ「ここまでの広がりになるということを、高市総理はどれだけ想像できていたんでしょうね」 日中問題特集で [冬月記者★]
- 「町中華」の“息切れ倒産”が増加 ブームにも支えられ職人技で踏ん張ってきたが… 大手チェーンは値上げでも絶好調 [ぐれ★]
- 毛寧(もう・ねい)報道官「中国に日本の水産品の市場は無い」 高市首相の国会答弁に「中国民衆の強い怒り」 ★2 [ぐれ★]
- 立民・岡田氏の質疑「不適切」 維新・藤田氏、台湾有事答弁巡り [蚤の市★]
- 【悲報】日本、自民党(統一教会)で完全崩壊か?年金制度実質破綻、生活保護、国民健康保険廃止へ [383063292]
- ㊗157円 [194819832]
- 【高市売り】円安、止まらず!凄い勢いで暴落中。157円へ [219241683]
- 高市早苗って「わざと」日本畳んでるよな? [419865925]
- ‎
- 1,000万円のBMWに擦ってしまった札幌のガキ、捕らえられてガチで詰む [329329848]
