mandiant / STrace

A DTrace on Windows Reimplementation
MIT License
329 stars 41 forks source link

STrace Installation Problem #35

Open Codekies opened 2 days ago

Codekies commented 2 days ago

Hi, I have some issues when I install Strace on my Windows 10 Pro VM machine (Version 22H2 (OS BUILD 19045.5131)) What I did the installation is download and unzip the release zip file (v.1.3.6 and v.1.3.1), move the files to the same folder as the script, and then run the PowerShell script in the install folder as admin. Thanks for the help

PS C:\Users\test\Downloads\STrace\install> .\install_as_admin.ps1

Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your
computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning
message. Do you want to run C:\Users\test\Downloads\STrace\install\install_as_admin.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): R
STrace Install: Root - C:\Users\test\Downloads\STrace\install
C:\Users\test\Downloads\STrace\install\STraceApiSet.reg C:\Users\test\Downloads\STrace\install\STraceDriver.reg
The operation completed successfully.
The operation completed successfully.
The operation completed successfully.
The operation completed successfully.

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
     18       4     1540       2028       0.00   5148   1 cmd

After Reboot (with F8 and disable DSE)

C:\Users\test\Downloads\STrace\install>bcdedit

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\Microsoft\Boot\bootmgfw.efi
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {default}
displayorder            {default}
                        {current}
                        {610b9929-ae17-11ef-8e18-806e6f6e6963}
toolsdisplayorder       {memdiag}
timeout                 30
displaybootmenu         Yes

Windows Boot Loader
-------------------
identifier              {default}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
displaymessageoverride  Recovery
recoveryenabled         Yes
nointegritychecks       Yes
testsigning             Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {610b9929-ae17-11ef-8e18-806e6f6e6963}
nx                      OptIn
bootmenupolicy          Legacy
dtrace                  Yes

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             STrace (Press F8 to disable DSE)
locale                  en-US
inherit                 {bootloadersettings}
displaymessageoverride  Recovery
recoveryenabled         Yes
nointegritychecks       Yes
testsigning             Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {610b9929-ae17-11ef-8e18-806e6f6e6963}
nx                      OptIn
bootmenupolicy          Legacy
dtrace                  Yes

Use CMD as Administrator to open STraceCLI.exe with LogSyscallsPlugin.dll and FileDeleteRecordPlugin.dll

C:\Users\test\Downloads\STrace\install>.\STraceCLI.exe
[+] Opening driver
[+] Driver Opened Successfully
Input command: load, unload, exit
load
[+] Asking for plugin
Input command: load, unload, exit
unload
[+] Unloading plugin
Input command: load, unload, exit

STrace.txt

21:29:31.643  INF #0   7308  Log has been initialized.
21:29:31.643  INF #0   7308  Starting DLL load
21:29:31.643  INF #0   7308  [+] Executing DLLMain
21:29:31.643  INF #0   7308  [+] DLL Load Done
21:29:31.643  INF #0   7308  [+] Dll Mapped at FFFF948387302000
21:29:31.643  INF #0   7308  Plugin Initializing...
21:29:31.643  INF #0   7308  Plugin Initialized

Do you have any idea about this bug? Thanks a lot for the help.

stevemk14ebr commented 2 days ago

What you shared has everything configured correctly and it looks like it's been able to load the driver and open communications in user mode. This is good.

I assume it's not hooking syscalls yet. You need to load one of the plugins, and ensure stpistarget matches your target binary conditions/name in the plugin.

If you still aren't able to hook things then reboot the machine a few times and rerun the install script the the bcdedit cmd commented out. Sometimes it just takes a few boots to get the kernel to invoke dtrace initialization

Logs are placed in root of C:\

Codekies commented 2 days ago

Thanks a lot for the help. Now the FileDeleteRecordPlugin.dll works but LogSyscallsPlugin.dll didn't work. What I did is open a notepad.exe, but it didn't work.

But here's is the FileDeleteRecordPlugin.dll's strace.txt

22:16:32.111  INF #0   1768  Log has been initialized.
22:16:32.111  INF #0   1768  Starting DLL load
22:16:32.111  INF #0   1768  [+] Executing DLLMain
22:16:32.111  INF #0   1768  [+] DLL Load Done
22:16:32.111  INF #0   1768  [+] Dll Mapped at FFFF9B0796B74000
22:16:32.111  INF #0   1768  Plugin Initializing...
22:16:32.111  INF #0   1768  Plugin Initialized
22:16:38.732  INF #1   7704  File \Device\HarddiskVolume3\Users\test\Desktop\test - Copy.cs deleted
22:16:38.732  INF #1   7704  File Backup Complete
22:16:38.732  INF #1   7704    [\SystemRoot\system32\ntoskrnl.exe] +0x008c0edb
22:16:38.732  INF #1   7704    [\SystemRoot\system32\ntoskrnl.exe] +0x00412c87
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\ntdll.dll] +0x0009d9d4
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x0051ab9e
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x00432af1
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x0028a639
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x0010507a
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x00101260
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x00100a10
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x00100aaf
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\windows.storage.dll] +0x00100384
22:16:38.732  INF #1   7704    [C:\Windows\System32\SHELL32.dll] +0x002390f9
22:16:38.732  INF #1   7704    [C:\Windows\System32\SHELL32.dll] +0x0024f269
22:16:38.732  INF #1   7704    [C:\Windows\System32\shcore.dll] +0x0002bd19
22:16:38.732  INF #1   7704    [C:\Windows\System32\KERNEL32.DLL] +0x00017374
22:16:38.732  INF #1   7704    [C:\Windows\SYSTEM32\ntdll.dll] +0x0004cc91
stevemk14ebr commented 2 days ago

Great! The driver is working then, that's the tricky part. The only thing you need to do is change https://github.com/mandiant/STrace/blob/main/C%2FLogSyscallsPlugin%2Fdllmain.cpp#L983 this target condition to match your process. You will need strstr rather than strcmp because the driver now passed the full file path of all processes and not just the file name as it previously did. Recompile the plugin and load your modified one. If you get confused on what processes are running you can modify this to always return true and just log the process names to ensure it's being called. Alternatively you can filter by PID if that's easier.

Codekies commented 2 days ago

Huge Thanks for that. Later on, I will sponsor this project and you saved my College Final Year Project (this is part of it, I am creating a stupid version of EDR). But I want to know that is around line 980

extern "C" __declspec(dllexport) void StpCallbackReturn(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo) {
    if (strcmp(callerinfo.processName, "test.exe") == 0) {
        LOG_INFO("[RETURN] %s %s\r\n", get_probe_name((PROBE_IDS)probeId), callerinfo.processName);
    }
}

to this new version (I am not sure this is correct or not, but I want to inspect all processes in the end, idk is that possible)

extern "C" __declspec(dllexport) void StpCallbackReturn(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo) {
    if (strstr(callerinfo.processName, "C:\\Windows\\system32\\notepad.exe") != NULL) {
        LOG_INFO("[RETURN] %s %s\r\n", get_probe_name((PROBE_IDS)probeId), callerinfo.processName);
    }
}
stevemk14ebr commented 2 days ago

No need to sponsor, I just ask you submit any prs if you build any interesting plugins.

That is roughly correct, but strstr is like a substring match so you just need to compare against your file name, not the full path. If you want to intercept all process remove all checks and just return true always from stpistarget

Codekies commented 2 days ago

Sorry to bother you again. But after I read some of the code, I have only found these 2 compared with my file name.

extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo & callerinfo) {
    if (strcmp(callerinfo.processName, "BasicHello.exe") == 0) {
        return true;
    }
    return false;
}
extern "C" __declspec(dllexport) void StpCallbackReturn(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo) {
    if (strcmp(callerinfo.processName, "test.exe") == 0) {
        LOG_INFO("[RETURN] %s %s\r\n", get_probe_name((PROBE_IDS)probeId), callerinfo.processName);
    }
}
ASSERT_INTERFACE_IMPLEMENTED(StpCallbackReturn, tStpCallbackReturnPlugin, "StpCallbackEntry does not match the interface type");

I guess what I need to do is remove the second one and change the first one to the one below.

extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo & callerinfo) {
    return true;
}

Thanks for the help.

stevemk14ebr commented 2 days ago

Yea that's correct!

In https://github.com/mandiant/STrace/commit/58547f054933e81e7fb9bbef0f40cd23cb110af5 I changed the kernel API that the driver used to retrieve the filename/file path. This API returns the full dos path to the file like //Device/hardrive0/C/blah/file.exe . I did not update the plugins yet so they all use a strcmp because the old API would just return the filename like file.exe. the plugins should be updated to use strstr but I didn't do this yet. Your code looks correct for what you want to do in order to trace all processes

Codekies commented 2 days ago

Sorry to bother you again. This time I want to exclude some executables like include dwm.exe, conhost.exe Version 1 still not work

extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo& callerinfo) {
    // List of processes to exclude
    const char* excludedProcesses[] = { "dwm.exe", "conhost.exe", "taskhostw.exe" };

    // Check if the current process name matches any of the excluded processes
    for (const char* excludedProcess : excludedProcesses) {
        if (strcmp(callerinfo.processName, excludedProcess) == 0) {
            return false; // Return false if it's one of the excluded processes
        }
        else {
            return true;
        }
    }

    // Return true for all other processes that are not excluded
    return false;
}
ASSERT_INTERFACE_IMPLEMENTED(StpIsTarget, tStpIsTarget, "StpIsTarget does not match the interface type");

Version 2 still not work too

extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo& callerinfo) {
    // List of processes to exclude
    const char* excludedProcesses[] = { "dwm.exe", "conhost.exe", "taskhostw.exe" };

    // Check if the current process name matches any of the excluded processes
    for (const char* excludedProcess : excludedProcesses) {
        if (strcmp(callerinfo.processName, excludedProcess) == 0) {
            return false; // Return false if it's one of the excluded processes
        }
    }

    // If no matches were found in the exclusion list, return true
    return true;
}

Thanks a lot for the help again.

stevemk14ebr commented 2 days ago

You are still using strcmp, as I mentioned that will not work because the driver return the full file path. Use strstr. Log the process name from callerinfo to see what I mean