长期以来,我一直对dnSpy着迷,它可以轻松地将 .NET 应用程序逆向工程为可读的 C#。所以我想知道是否有类似于 RE Windows 10 UWP 应用程序的工具?
例如,我C:\Program Files\WindowsApps\Microsoft.WindowsStore_12002.1001.1.0_x64__8wekyb3d8bbwe\WinStore.App.exe
在 dnSpy 中尝试了 Microsoft Settings 应用程序,它只给了我基本的 PE 结构:
长期以来,我一直对dnSpy着迷,它可以轻松地将 .NET 应用程序逆向工程为可读的 C#。所以我想知道是否有类似于 RE Windows 10 UWP 应用程序的工具?
例如,我C:\Program Files\WindowsApps\Microsoft.WindowsStore_12002.1001.1.0_x64__8wekyb3d8bbwe\WinStore.App.exe
在 dnSpy 中尝试了 Microsoft Settings 应用程序,它只给了我基本的 PE 结构:
UWP 是一个容器/平台,根据可执行内容需要不同的逆向技术。.NET UWP 应用程序可以编译为 CLR,然后您可以使用标准的 .NET 反编译技术,即 JustDecompile、.NET Reflector 等。要识别它是否是 .NET,您可以使用CFF Explorer等工具,它会列出文件如果 .NET 工具适合,请键入Portable Executable 32/64 .NET Assembly。您还将看到在导入目录中列出了mscoree.dll。
但是,UWP .NET 应用程序也可以编译为.NET Native 。此外,UWP 应用程序可以用C++/CX编写并直接编译为本机代码。
这些将在 CFF 资源管理器中显示为Portable Executable 32/64
如果我们在诸如 IDA Pro 之类的本机代码逆向工具中查看WinStore.App.exe,我们可以看到它从WinStoreApp.dll导入RHBinder_ShimExeMain并且它的入口点只是跳转到这个:
public start
start proc near
jmp cs:RHBinder__ShimExeMain
start endp
我们打开这个DLL,看到这个函数:
public RHBinder__ShimExeMain
RHBinder__ShimExeMain proc near
push rbp
mov rbp, rsp
sub rsp, 20h
call sub_1817A55B4
lea rsp, [rbp+0]
pop rbp
retn
RHBinder__ShimExeMain endp
它只是调用这个函数:
sub_1817A55B4 proc near
; __unwind { // 182523A80
push rbp
mov rbp, rsp
sub rsp, 30h
lea rax, [rbp-10h]
call cs:RhpReversePInvoke
call cs:CreateCommandLine
mov rcx, rax
call sub_18173A000
xor eax, eax
lea rcx, [rbp-10h]
call cs:RhpReversePInvokeReturn
lea rsp, [rbp+0]
pop rbp
retn
; } // starts at 1817A55B4
sub_1817A55B4 endp
使用像 Hex Rays Decompiler 这样的工具,您可以获得 C 中的伪代码表示:
__int64 sub_1817A55B4()
{
__int64 v0; // rax
char v2[16]; // [rsp+20h] [rbp-10h] BYREF
RhpReversePInvoke();
v0 = CreateCommandLine();
sub_18173A000(v0);
return RhpReversePInvokeReturn(v2);
}
如果我们查看 DLL 的 DllEntryPoint,我们会发现以下内容:
BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
BOOL result; // eax
if ( *(_QWORD *)&fdwReason == 1i64 )
result = sub_1817A5650(hinstDLL, 1i64, lpReserved);
return result;
}
如果我们遵循 sub_1817A5650 和它调用的子函数,我们最终会在:
__int64 sub_1817A55FC()
{
char v1[16]; // [rsp+20h] [rbp-10h] BYREF
RhpReversePInvoke();
RhpSuppressGcStress();
RhpRegisterModule(&unk_180001000);
nullsub_1();
nullsub_1();
nullsub_1();
nullsub_1();
RhpUnsuppressGcStress();
return RhpReversePInvokeReturn(v1);
}
unk_180001000 指向以下内容:
弄清楚这些 API 调用的目的和此数据结构将帮助您反转 UWP 应用程序。
我会使用IDA Pro 和 Hex Rays Decompiler或Ghidra 等工具
但是,如果您来自 .NET 反编译,请不要指望这几乎如此简单,或者使用自动工具生成看起来几乎可编译的代码的结果。反转本机代码需要付出更多的努力。
如果我们使用File -> Launch App Package方法从 Windows 商店启动带有WinDbg Preview的应用程序,我们可以看到此应用程序在加载模块时加载 .NET Native 运行时。这解释了为什么标准的 .NET 逆向工具不能在这个 EXE 上工作:
ModLoad: 00007ff9`b6280000 00007ff9`b6306000 C:\Program Files\WindowsApps\Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x64__8wekyb3d8bbwe\mrt100_app.dll
ModLoad: 00007ff9`b34f0000 00007ff9`b41bd000 C:\Program Files\WindowsApps\Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x64__8wekyb3d8bbwe\SharedLibrary.dll
如果试图确定某些特定行为的工作方式,使用调试器可能会更容易。
应用程序文件夹中的Windows 元数据 (WinMD)文件可以使用一些 .NET 反编译器工具浏览,并允许您浏览接口/类型定义,但据我所知,这些文件不包含代码。
与使用 CLR 字节码的 .NET 应用程序不同,UWP 应用程序主要是本机代码。本机代码 更难分析和反编译。