2ちゃんねる スマホ用 ■掲示板に戻る■ 全部 1- 最新50    

■ このスレッドは過去ログ倉庫に格納されています

アセンブリや機械語を解析して楽しむスレ

1 :デフォルトの名無しさん:2021/06/19(土) 17:16:50.94 ID:KpP01EPy.net
5ちゃんねるの総力を挙げて、人力でアセンブリや機械語を逆コンパイルするスレッドです。コード解析の達人やヒマ人の皆様、ご協力下さい。

===依頼テンプレここから===
【依頼の目的と内容説明】ここに目的と説明を書く
【プロセッサの種類】x86/x64/ARM/JVM など
【OSの種類】Windows/Linux/Mac/Android/iOS など
【言語】C/C++/Java/C# など
【報酬金額と送金方法】報酬なし/銀行振込/WebMoney など
【アセンブリまたは機械語】以下にアセンブリまたは機械語を記載
===依頼テンプレここまで===

依頼は一度に1関数までとします。あまりにも長いコードは人力では逆コンパイルできません。常識の範囲でご利用ください。

48 :デフォルトの名無しさん:2021/06/24(木) 22:06:26.29 ID:KFTtHP2O.net
だとすれば、形式言語で書くと
```asm
push eax
pop ebx
```
[==]
```asm
mov ebx, eax
```
とか、
```asm
xor eax, eax
```
[==]
```asm
mov eax, 0
```
とか書けますね(だからどうした

49 :デフォルトの名無しさん:2021/06/24(木) 22:14:16.13 ID:KFTtHP2O.net
形式言語はバッククォート表記のせいで無駄に行数を喰いますね。

「push eax; pop ebx」[==]「mov ebx, eax」
これじゃいけないんすか?

50 :デフォルトの名無しさん:2021/06/24(木) 22:36:01.24 ID:GPZ7ub3d.net
>>49
ちゃんと言語名を明記すべき。行区切りは全角の「/」にしよう。

asm「push eax/pop ebx」[==] asm「mov ebx, eax」

これならバッククォート表記と整合性が図れる。
でも全角文字は英語圏では使いづらいので日本語圏に限定するしかない。

51 :デフォルトの名無しさん:2021/06/24(木) 22:51:38.01 ID:GPZ7ub3d.net
要するに、アセンブリとC/C++言語の中間言語「cr2言語(仮)」を考えているんだろ。

アセンブリは広大な言語空間だから、素人の人間が手作業でちまちまやっていたら
何カ月経っても制覇できない。

インターネットで公開データが気軽にダウンロードできる時代だから、
データ指向でCPUの全命令を一気に網羅することを考えないといけない。
生データがなければウェブからスクレイピングするとか。。。

x86/x64 CPU の仕様は
「Intel 64 and IA-32 Architectures Software Developer’s Manual」に
全部書かれていて、PDFファイルとしてダウンロードできる(一次情報)。

52 :デフォルトの名無しさん:2021/06/24(木) 23:03:34.25 ID:GPZ7ub3d.net
ほらよ:
https://github.com/netwide-assembler/nasm/blob/master/x86/insns.dat

全部で6256行あるぜ。これを手作業で変換処理を書くつもりか???

正気かよ

53 :デフォルトの名無しさん:2021/06/24(木) 23:16:42.66 ID:KFTtHP2O.net
>>52
ありがとう
早速解読してみるね。なんか英語で書かれてて難しそう。。。

54 :デフォルトの名無しさん:2021/06/25(金) 00:46:15.53 ID:xLwe8284.net
解読していくと。。。
使い方を知りたいならinsns.plを読みなさいと。
拡張子.plはPerlだよな。
うわ、こんな所でPerlが出てくるのか。

55 :デフォルトの名無しさん:2021/06/25(金) 01:46:22.63 ID:xLwe8284.net
https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b

こんなサイトをスクレイピングすれば〜?

56 :デフォルトの名無しさん:2021/06/25(金) 12:06:59.81 ID:W5hhXd/9.net
【依頼の目的と内容説明】 user32.dll/imm32.dllの解析
【プロセッサの種類】 x86 【OSの種類】 Win Server 2003 【言語】 C/C++
【報酬金額と送金方法】 報酬なし
【アセンブリまたは機械語】
proc user32.dll!CliImmSetHotKey@16 Label_773C7479
Label_773C7479:
mov edi, edi
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+0x10]
xor eax, eax
test edi, edi
setz al
test eax, eax
jz Label_773C74A6
push eax
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func773C7273@20
mov esi, eax
test esi, esi
jnz Label_773C74D4
jmp Label_773C74E5
Label_773C74A6:
push 0x2 # jump_from : 773C748C
push dword [ebp+0x14]
(...続く...)

57 :デフォルトの名無しさん:2021/06/25(金) 12:07:44.35 ID:W5hhXd/9.net
...(続き)...
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func77384A58@20
mov esi, eax
test esi, esi
jz Label_773C74E5
push 0x0
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func773C7273@20
mov esi, eax
test esi, esi
jnz Label_773C74E5
Label_773C74D4:
push 0x1 # jump_from : 773C74A2
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func77384A44@20
Label_773C74E5:
pop edi # jump_from : 773C74A4 773C74BB 773C74D2
mov eax, esi
pop esi
pop ebp
ret 0x10
end proc
よろしくお願いします。

58 :デフォルトの名無しさん:2021/06/25(金) 13:00:01.37 ID:W5hhXd/9.net
>>56-57
asm「mov edi, edi」
[=>] txt「何もしない。」

asm「push ebp/mov ebp, esp」
[=>] txt「スタックフレームを確立する。
EBP=ESP=[(old bpb), (ret. addr.), CliImmSetHotKey.#1, CliImmSetHotKey.#2, CliImmSetHotKey.#3, CliImmSetHotKey.#4].」

asm「push esi/push edi」
[=>] txt「esiをプッシュする。ediをプッシュする。
ESP=[(old edi), (old esi), (old bpb), (ret. addr.), CliImmSetHotKey.#1, CliImmSetHotKey.#2, ...].」

asm「mov edi, [ebp+0x10]/xor eax, eax/test edi, edi/setz al/test eax, eax/jz Label_773C74A6」
[=>]
```txt
edi = CliImmSetHotKey.#3;
eax = 0;
ZeroFlag = (edi == 0);
al = (ZeroFlag == TRUE);
if (eax == 0) goto Label_773C74A6;
```
...(続く)...

59 :デフォルトの名無しさん:2021/06/25(金) 13:01:12.12 ID:W5hhXd/9.net
...(続き)...
```asm
push eax
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func773C7273@20
```
[=>]
```txt
assert(eax == 1);
eax = Func773C7273(CliImmSetHotKey.#1, CliImmSetHotKey.#2, edi, CliImmSetHotKey.#4, eax);
```
asm「mov esi, eax/test esi, esi/jnz Label_773C74D4/jmp Label_773C74E5」
[=>] txt「esi = eax;/ZeroFlag = (esi == 0);/if (!ZeroFlag) goto Label_773C74D4;/goto Label_773C74E5;」

```asm
Label_773C74A6:
push 0x2 # jump_from : 773C748C
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func77384A58@20
```
[=>]
```txt
Label_773C74A6:
eax = Func77384A58(CliImmSetHotKey.#1, CliImmSetHotKey.#2, edi, CliImmSetHotKey.#4, 0x2);
```
...(続く)...

60 :デフォルトの名無しさん:2021/06/25(金) 13:02:50.65 ID:W5hhXd/9.net
...(続き)...
asm「mov esi, eax/test esi, esi/jz Label_773C74E5」
[=>] txt「esi = eax;/ZeroFlag = (esi == 0);/if (ZeroFlag) goto Label_773C74E5;」
```asm
push 0x0
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func773C7273@20
```
[=>] txt「eax = Func773C7273(CliImmSetHotKey.#1, CliImmSetHotKey.#2, edi, CliImmSetHotKey.#4, 0);」

asm「mov esi, eax/test esi, esi/jnz Label_773C74E5」
[=>] txt「esi = eax;/if (esi != 0) goto Label_773C74E5;」

```asm
Label_773C74D4:
push 0x1 # jump_from : 773C74A2
push dword [ebp+0x14]
push edi
push dword [ebp+0xc]
push dword [ebp+0x8]
call Func77384A44@20
```
[=>]
```txt
Label_773C74D4:
eax = Func77384A44(CliImmSetHotKey.#1, CliImmSetHotKey.#2, edi, CliImmSetHotKey.#4, 1);
```
...(続く)...

61 :デフォルトの名無しさん:2021/06/25(金) 13:03:52.02 ID:W5hhXd/9.net
...(続き)...
```asm
Label_773C74E5:
pop edi # jump_from : 773C74A4 773C74BB 773C74D2
mov eax, esi
pop esi
pop ebp
ret 0x10
```
[=>]
```txt
Label_773C74E5:
eax = esi;
スタックフレームを破棄する。
return eax;
```

以上を簡略化し、ImmSetHotKeyのプロトタイプが
BOOL WINAPI ImmSetHotKey(DWORD dwHotKeyID, UINT uModifiers, UINT uVKey, HKL hKL);
であることを鑑みると

...(続く)...

62 :デフォルトの名無しさん:2021/06/25(金) 13:04:32.70 ID:W5hhXd/9.net
...(続き)...

```c
BOOL CliImmSetHotKey(DWORD dwHotKeyID, UINT uModifiers, UINT uVKey, HKL hKL)
{
__BOOL ret;
__if (uVKey != 0)
__{
____ret = Func773C7273(dwHotKeyID, uModifiers, uVKey, hKL, 1);
____if (ret != 0)
______Func77384A44(dwHotKeyID, uModifiers, uVKey, hKL, 1);
____return ret;
__}
__ret = Func77384A58(dwHotKeyID, uModifiers, uVKey, hKL, 2);
__if (ret == 0)
____return ret;
__ret = Func773C7273(dwHotKeyID, uModifiers, uVKey, hKL, 0);
__if (ret != 0)
____return ret;
__Func77384A44(dwHotKeyID, uModifiers, uVKey, hKL, 1);
__return ret;
}
```
となって逆コンパイルが完了する。 □

63 :デフォルトの名無しさん:2021/06/25(金) 13:36:57.11 ID:W5hhXd/9.net
【依頼の目的と内容説明】 user32.dll/imm32.dllの解析
【プロセッサの種類】 x86 【OSの種類】 Win Server 2003 【言語】 C/C++
【報酬金額と送金方法】 報酬なし
【アセンブリまたは機械語】
proc Func77384A44@20 Label_77384A44
Label_77384A44:
mov eax, 0x1201
mov edx, 0x7ffe0300
call dword [edx]
ret 0x14
end proc

解読お願いします。

[0x7ffe0300]は、ntdll!KiFastSystemCallであることが分かっています。

64 :デフォルトの名無しさん:2021/06/25(金) 23:03:34.71 ID:W5hhXd/9.net
>>63
NtUserSetImeHotKey関数をシステムコール経由で呼んでいるらしい。
https://reactos.org/wiki/Techwiki:Win32k/syscalls

これ以上のことは分からない。

65 :デフォルトの名無しさん:2021/06/26(土) 23:13:53.65 ID:RPMP544+.net
こっちでまとめてます。秘密基地です。
https://github.com/katahiromz/secret_base

66 :デフォルトの名無しさん:2021/06/29(火) 20:06:52.90 ID:+6dhbc6a.net
```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のトリック。

67 :デフォルトの名無しさん:2021/07/13(火) 10:27:53.03 ID:M2x6Ny3W.net
riscはオナニーしながらでも読めるにゃ

68 :デフォルトの名無しさん:2021/07/13(火) 11:39:35.80 ID:EvOOyjG8.net
はやっ

69 :デフォルトの名無しさん:2021/07/14(水) 01:35:31.92 ID:lv8+vNga.net
>>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の論理否定となる。

70 :デフォルトの名無しさん:2021/08/03(火) 21:07:31.90 ID:Q9+5cbUY.net
```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)) {
...
}
...
```
に書き換えることができる。

71 :デフォルトの名無しさん:2021/08/03(火) 21:09:13.31 ID:Q9+5cbUY.net
>>70は書き損じだから無視して。


```txt
Label_YYYY:
...
if (exp) goto Label_YYYY;
```
は、
```txt
do
...
} while (exp);
```
に置き換えることができる。


```txt
if (exp) goto Label_XXXX;
...
Label_XXXX:
...
```
は、
```txt
if (!(exp)) {
...
}
...
```
に書き換えることができる。

72 :デフォルトの名無しさん:2021/08/03(火) 21:16:45.35 ID:Q9+5cbUY.net
ジャンプ命令は基本的に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;
```
に置き換え可能。

73 :デフォルトの名無しさん:2021/08/04(水) 15:25:34.02 ID:YCRiyQzz.net
if (exp)

74 :デフォルトの名無しさん:2021/08/04(水) 15:26:28.93 ID:YCRiyQzz.net
```txt
if (exp)
{
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp)
{
...
}
else
...
Label_XXXX:
```

75 :デフォルトの名無しさん:2021/08/04(水) 15:27:12.21 ID:YCRiyQzz.net
```txt
if (exp) {
...
goto Label_XXXX;
}
...
Label_XXXX:
```
は、
if (exp) {
...
} else {
...
}
Label_XXXX:
```
に置き換え可能。

76 :デフォルトの名無しさん:2021/08/13(金) 14:20:39.59 ID:xGO78+x4.net
ImmAssociateContext
ImmAssociateContextEx
ImmConfigureIMEA/W
ImmEscapeA/W
Imm32GetClientImcCache
ImmGetCompositionStringA/W
ImmGetContext
ImmInstallIMEW
ImmIsUIMessageA/W
ImmRequestMessageA/W
ImmSetCompositionStringA/W
ImmGetImeMenuItemsA/W
ImmLockIMC
ImmGenerateMessage
ImmTranslateMessage
ImmProcessKey
ImmSetActiveContext

宿題がまだこ〜んなにあるぜ。本当に全部できるのかよ。

77 :デフォルトの名無しさん:2021/09/24(金) 02:14:10.10 ID:i//SzVJC.net
まあ、これを見て実際の逆工学をやってみるもよし

https://github.com/katahiromz/DecodersTatami/blob/main/target/analysis/Func00401550.txt

セキュリティエンジニアの道ははるかに遠い

78 :デフォルトの名無しさん:2021/09/25(土) 20:48:50.24 ID:H+l7h9ZE.net
とりあえず、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ビット整数。

79 :デフォルトの名無しさん:2021/09/25(土) 20:52:28.04 ID:H+l7h9ZE.net
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だ。

80 :デフォルトの名無しさん:2021/09/25(土) 21:08:38.10 ID:+1RCibwo.net
eaxの中にaxレジスタがあり、axレジスタの中にal, ahレジスタがあるという見方もできる。このような構造になっているのは16ビットとの互換性のためである。

64ビットCPUのx64、別名amd64ではrax, rbx, rcx, rdxというように、頭にrが付いた64ビットレジスタが増設された。逆工学の主な戦場はまだ32ビットにあるが、今後64ビットを対応しないといけない。

81 :デフォルトの名無しさん:2021/09/28(火) 20:27:04.96 ID:m9n91EHz.net
【問題】
```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
```
[=>]

82 :デフォルトの名無しさん:2021/09/28(火) 20:29:43.46 ID:m9n91EHz.net
```txt
edi = eax;
ecx = 0x30;
```
である。□

```asm
push (即値)
pop (レジスタX)
```
[=>]
```txt
(レジスタX) = (即値);
```
はpush-popトリックだから覚えておいてね。

83 :デフォルトの名無しさん:2022/01/17(月) 19:44:42.22 ID:32ay/bkz.net
今回は、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検索します。

84 :デフォルトの名無しさん:2022/01/17(月) 19:45:19.85 ID:32ay/bkz.net
これをDecodersTatamiに掛けてdeadfaceをgrep検索します。
main関数が見つかります。呼び出しツリーは以下のようになります。

main
...→ Func00401341 // SetFileInformationByHandle
......→ Func0040105F
......→ Func004010B9
...→ Func0040122D // GetFileInformationByHandleEx
......→ Func00401032
......→ Func004010B9
...→ Func004010D7 // OpenFileById
......→ Func004010B9

というわけで、最初にFunc004010B9を解読します。

85 :デフォルトの名無しさん:2022/01/17(月) 19:46:57.43 ID:32ay/bkz.net
【依頼の目的と内容説明】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
```

86 :デフォルトの名無しさん:2022/01/17(月) 19:50:05.81 ID:32ay/bkz.net
これは非常に簡単だ。

```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;
}
```

87 :デフォルトの名無しさん:2022/01/17(月) 19:53:15.58 ID:32ay/bkz.net
おそらく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

88 :デフォルトの名無しさん:2022/01/17(月) 20:00:34.53 ID:32ay/bkz.net
解読する。

```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']
```

89 :デフォルトの名無しさん:2022/01/17(月) 20:05:56.89 ID:32ay/bkz.net
次の結果が得られる。

```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);
である。

90 :デフォルトの名無しさん:2022/01/17(月) 20:06:48.16 ID:32ay/bkz.net
よって整理すると

```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);
}
```



続きはまた明日。

91 :デフォルトの名無しさん:2022/01/18(火) 10:34:45.36 ID:kpMFjbVI.net
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
```

92 :デフォルトの名無しさん:2022/01/18(火) 10:36:01.65 ID:kpMFjbVI.net
これも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のプロトタイプは

93 :デフォルトの名無しさん:2022/01/18(火) 10:36:31.35 ID:kpMFjbVI.net
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);
}



94 :デフォルトの名無しさん:2022/01/18(火) 10:45:00.41 ID:kpMFjbVI.net
次は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トリック。

95 :デフォルトの名無しさん:2022/01/18(火) 10:45:21.84 ID:kpMFjbVI.net
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);

であるから、

96 :デフォルトの名無しさん:2022/01/18(火) 10:45:51.37 ID:kpMFjbVI.net
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);
}



続きは明日やろう。

97 :デフォルトの名無しさん:2022/11/28(月) 18:36:01.95 ID:QIQXhRT5.net
明日は来ない

総レス数 97
58 KB
掲示板に戻る 全部 前100 次100 最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★