# Frida 102: Tracing and Hooking Windows APIs

# 1\. Frida hoạt động như thế nào?

Để có thể lấy được các thông tin trong khi một chương trình đang chạy hay thay đổi hành vi của nó thì **Frida** sử dụng một kỹ thuật gọi là **Hooking**. Frida cài đặt các hook tại các hàm của chương trình mục tiêu, Hook code sử dụng ngôn ngữ lập trình JavaScript. Để đơn giản thì có thể hiểu như sau: Khi Frida hook vào một hàm, chúng ta giám sát được đầu vào và đầu ra của hàm (tham số truyền vào và giá trị trả về), sửa đổi các giá trị đó hoặc thậm chí là cho hàm đó thực thi code của chúng ta thay vì code gốc,.v.v.. Những việc này đều thực hiện trong lúc chương trình chạy, mọi thay đổi đều diễn ra trên memory mà không làm thay đổi tệp chương trình. Kỹ thuật Hook được ứng dụng trong nhiều tình huống khác nhau, với mục đích tốt có mà xấu cũng có.

Để có thể **Hook** vào một chương trình, Frida tiến hành Inject một **DLL** có tên là `frida-agent.dll` vào bên trong vùng nhớ của chương trình đó khi nó đang chạy. Frida sử dụng các APIs trong `dbghelp.dll` để tra cứu các **Symbols** trên Windows, ngoài ra kể từ phiên bản `12.9.8` trở đi Frida đã hỗ trợ việc lookup các Symbol thông qua một Symbol Server. Những cải tiến này đến từ các chuyên gia của **DarunGrim Company** đã đóng góp cho dự án Frida.

Hình dưới đây mô tả cách Frida có thể lookup các Symbol trên Windows:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/4d5a95bb-dcf6-4f00-bf49-946b438d0da4.png align="center")

Tham khảo: https://darungrim.com/research/2020-06-17-using-frida-for-windows-reverse-engineering.html

Sử dụng [**Process Explorer**](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) trong bộ Sysinternal Suite có thể quan sát được, Frida đã inject `frida-agent.dll` vào bên trong `notepad.exe`:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/91613a5f-f317-4869-adad-51c7248c1aba.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e329d77f-7a41-4d03-a25d-e9cb0616fd58/Untitled.png align="center")

Trước đó Frida giải nén các tệp cần thiết mà nó sử dụng vào thư mục: `%LOCALAPPDATA%\Temp\frida-<random-32-character>\<32|64>` ứng với tệp chương trình 32-bits hoặc 64-bits. Cấu trúc trông như sau:

```bash
$ tree
.
├── 32
│   ├── dbghelp.dll
│   ├── frida-agent.dll
│   └── symsrv.dll
└── 64
    ├── dbghelp.dll
    ├── frida-agent.dll
    └── symsrv.dll

2 directories, 6 files
```

Sơ đồ dưới đây mô tả cách mà Frida cài đặt các Hook và nhận thông báo từ các hook đã cài:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/9f0a3f2f-f790-4034-97cc-5b46512ee1e6.png align="center")

Tham khảo: https://darungrim.com/research/2020-06-17-using-frida-for-windows-reverse-engineering.html

Các đối tượng `Frida`, `Session`, `Script` tham gia vào quá trình này để quản lý cài đặt các Hook. Các **Hook CallBack Functions** được viết bằng **JavaScript**.

# 2\. Sử dụng Frida cơ bản

## 2.1. Khởi chạy một chương trình bằng Frida

```powershell
$ frida C:\Windows\System32\notepad.exe
     ____
    / _  |   Frida 14.2.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
Spawned `C:\Windows\System32\notepad.exe`. Use %resume to let the main thread start executing!
[Local::notepad.exe]->
```

Lúc này tiến trình `notepad.exe` là tiến trình con được sinh ra bởi `Frida`:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/c14d6ce0-6e15-47d1-bf17-3742b99af75a.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f244feaf-7716-4c0e-b0f7-c8c5c7bafc2d/spawn_process.png align="center")

Trong bộ công cụ `frida-tools`, chúng ta có một chương trình là `frida-ps` có thể liệt kê tất cả các tiến trình đang chạy trên hệ thống. Có thể sử dụng nó để xác nhận `notepad.exe` đã được khởi chạy:

```powershell
$ frida-ps | findstr "notepad"
 14340  notepad.exe
```

## 2.2. Attach một tiến trình bằng Frida

Để attach một tiến trình bằng `Frida`, chúng ta phải tìm được PID của tiến trình cần attack sau đó sử dụng tham số `-p` của **Frida**:

```powershell
$ frida-ps | findstr "mspaint"
 7800  mspaint.exe
```

```powershell
$ frida -p 7800
     ____
    / _  |   Frida 14.2.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/

[Local::PID::7800]->
```

## 2.3. Sử dụng Frida Tracing

`frida-trace` là một công cụ trong bộ `frida-tools`. Công cụ này có thể Tracing/Monitor các API được gọi trong một chương trình. Giả sử chúng ta cần monitor hàm `MessageBox` và `WriteFile` trong `notepad.exe`.

```powershell
$ frida-trace -i "MessageBoxW" -i "WriteFile" C:\Windows\System32\notepad.exe
```

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/f036c27a-9ea5-4e21-bdad-ceef8c1f2f7d.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/05b6be54-e534-4c51-884c-069d8b294d45/messagebox_trace.png align="center")

# 3\. Hooking Windows APIs bằng Frida

## 3.1. APIs Monitor với Frida

Có thể sử dụng Frida để hook vào một số hàm nào đó trong một chương trình với mục đích chặn bắt các tham số của hàm, thậm chí là sửa đổi các tham số này (Memory Patching). Trong trường hợp này tôi thử nghiệm hook vào hàm `WriteFile` và `MessageBoxW` của chương trình `notepad.exe`. Trước tiên, hãy cùng xem xét các hàm này được định nghĩa như thế nào trong tài liệu MSDN của Microsoft.

```cpp
BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);
```

```cpp
int MessageBoxW(
  HWND    hWnd,
  LPCWSTR lpText,
  LPCWSTR lpCaption,
  UINT    uType
);
```

Tham số `lpBuffer` của hàm `WriteFile` chính là con trỏ trỏ đến vùng đệm sẽ được ghi vào tệp. Theo thứ tự thì hàm này sẽ là tham số thứ hai. Tham số `lpText` của hàm `MessageBoxW` là nội dung sẽ hiển thị trên box, `lpCaption` là tiêu đề của box khi hiển thị.

Khi `Frida` hook vào các hàm ta chỉ định trong `notepad.exe`. Ta thực hiện một số hành động sau:

*   Dump nội dung và in ra màn hình giá trị của `lpBuffer` trong hàm `WriteFile`
    
*   In ra màn hình nội dung của `lpText` và `lpCaption` trong hàm `MessageBoxW`
    

```jsx
var messageBox = Module.getExportByName(null, "MessageBoxW");
var writeFile = Module.getExportByName(null, "WriteFile");

Interceptor.attach(messageBox, {
    onEnter: function(args)
    {
		console.log("\nMessageBoxW at: " + messageBox);
        console.log("  lpText: " + Memory.readUtf16String(args[1]));
        console.log("  lpCaption: " + Memory.readUtf16String(args[2]));
    }
});

Interceptor.attach(writeFile, {
    onEnter: function(args)
    {
		console.log("\nWriteFile at: " + writeFile);
        console.log("  Buffer dump:\n" + hexdump(args[1]));
        console.log("  Buffer via utf16String: " + Memory.readUtf16String(args[1]));
    }
});
```

Lưu đoạn **JavaScript** này lại. Tôi đặt là `apis_hooking.js`. Khởi chạy lại `notepad.exe` với tham số `-l` để nạp script vừa viết:

```powershell
$ frida -l .\hooking\apis_hooking.js C:\Windows\System32\notepad.exe --no-pause
```

Nhập một nội dung bất kỳ, ở đây tôi nhập chuỗi: `"This is fun!"`, sau đó tiến hành lưu tệp ra ổ cứng và quan sát trong `Frida` ta được như sau:

```powershell
WriteFile at: 0x7fff9f8b4fd0
  Buffer dump:
              0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
1e1a2823780  54 00 68 00 69 00 73 00 20 00 69 00 73 00 20 00  T.h.i.s. .i.s. .
1e1a2823790  66 00 75 00 6e 00 21 00 00 00 00 00 00 00 00 00  f.u.n.!.........
...
1e1a2823870  00 00 00 00 00 00 00 00 10 39 82 a2 e1 01 00 00  .........9......
  Buffer via utf16String: This is fun!
```

Tìm kiếm một chuỗi không tồn tại, mục đích để `Notepad` bắn ra MessageBox:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/87875932-d969-41d2-a935-79736d6a5498.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/18891c38-4eb4-4a38-bc28-8372cdb041ff/messagebox_args.png align="center")

## 3.2. Memory Patching bằng Frida

`Frida` có một ưu điểm đó là trong lúc đang thực hiện hooking vào `notepad.exe` chúng ta có thể sửa mã JavaScript mà không cần phải chạy lại Frida, mã chúng ta sửa ngay lập tức được cập nhật. Chúng ta tiến hành sửa đoạn JavaScript trước đó thành như sau:

```jsx
var messageBox = Module.getExportByName(null, "MessageBoxW");
var writeFile = Module.getExportByName(null, "WriteFile");
var buff = Memory.allocUtf16String("F*ck y0u!!!!!!!")

Interceptor.attach(messageBox, {
    onEnter: function(args)
    {
		args[1] = buff
		args[2] = buff
		console.log("\nMessageBoxW at: " + messageBox);		
        console.log("  lpText: " + Memory.readUtf16String(args[1]));
        console.log("  lpCaption: " + Memory.readUtf16String(args[2]));
    }
});

Interceptor.attach(writeFile, {
    onEnter: function(args)
    {
		args[1] = buff
		console.log("\nWriteFile at: " + writeFile);
        console.log("  Buffer dump:\n" + hexdump(args[1]));
        console.log("  Buffer via utf16String: " + Memory.readUtf16String(args[1]));
    }
});
```

Kết quả sau khi hook hàm `MessageBoxW`

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/ca0df6b4-a155-4b80-806a-c6117851c5b1.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/447ded79-eb0a-40e8-b372-dd37982a35ef/messagebox_hooked.png align="center")

Kết quả sau khi hook hàm `WriteFile`

```powershell
WriteFile at: 0x7fff9f8b4fd0
  Buffer dump:
              0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
1e1a4376d40  46 00 2a 00 63 00 6b 00 20 00 79 00 30 00 75 00  F.*.c.k. .y.0.u.
1e1a4376d50  21 00 21 00 21 00 21 00 21 00 21 00 21 00 00 00  !.!.!.!.!.!.!...
..
1e1a4376e30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  Buffer via utf16String: F*ck y0u!!!!!!!
```

## 3.3. Chặn bắt thông tin xác thực trên Windows 10

Sử dụng `Frida` để chặn bắt thông tin xác thực người dùng. Đầu tiên hãy kiểm tra PID của tiến trình `explorer`. Chúng ta cần kiểm tra tiến trình này là vì thông thường khi chạy một chương trình thì nó là tiến trình con của `explorer`.

```powershell
$ frida-ps | findstr "explorer"
20128  explorer.exe
```

Sử dụng `Frida-Trace` để theo dõi các API được gọi đến trong quá trình xử lý dữ liệu xác thực từ người dùng. Tôi sử dụng tham số `-i "*Cred*"` để lọc các API chứa chuỗi `Cred`, `-x "CredFree"` sẽ không theo dõi hàm `CredFree()`.

```powershell
$ frida-trace -i "*Cred*" -x "CredFree" -p 20128
```

Khởi chạy chương trình `C:\Windows\System32\notepad.exe` với tùy chọn `Run as different user`

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/cfcb8c6e-8e7d-4764-984c-9595059368b8.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/df05a388-f0a3-4075-b224-2d2fbeadc585/run_as_diff_user.png align="center")

Lúc này một hộp thoại `Windows Security` xuất hiện đòi chúng ta nhập thông tin xác thực. Đồng thời ta quan sát trong `Frida`, hàm `CredUIPromptForWindowsCredentialsW()` được gọi:

```powershell
Started tracing 159 functions. Press Ctrl+C to stop.
           /* TID 0x42c0 */
 90061 ms  CredUIPromptForWindowsCredentialsW()
 90061 ms     | CredUIInternalPromptForWindowsCredentialsW()
 90061 ms     |    | CredUIInternalPromptForWindowsCredentialsWorker()
```

Nhập đại một vài thông tin nào đó sau đó nhấn OK.

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/84acd78a-3176-4efa-96e8-dd7099ad8cd9.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fa3a6e3c-b74f-42e1-9f67-648949ff767c/windows_security_promp.png align="center")

Quan sát trong `Frida` ta thấy một số API thú vị sau được gọi:

```powershell
257149 ms  CredUnPackAuthenticationBufferW()
257149 ms  CredUnPackAuthenticationBufferW()
257149 ms     | CredUnprotectW()
257149 ms     |    | CredUnprotectEx()
257149 ms     |    |    | CredUnmarshalCredentialW()
257149 ms  CredUIParseUserNameW()
257149 ms     | CredIsMarshaledCredentialW()
257149 ms     |    | CredUnmarshalCredentialW()
257150 ms  CredUIPromptForWindowsCredentialsW()
257150 ms     | CredUIInternalPromptForWindowsCredentialsW()
257150 ms     |    | CredUIInternalPromptForWindowsCredentialsWorker()
```

Chúng ta không cần quan tâm đến đoạn: `257150 ms CredUIPromptForWindowsCredentialsW()` vì đoạn này lặp lại đoạn trước đó, nó hiển thị hộp thoại `Windows Security` đòi nhập thông tin xác thực. Hàm cần quan tâm nhiều hơn là `CredUnPackAuthenticationBufferW()`. Cùng xem định nghĩa của hàm này trên MSDN:

```cpp
CREDUIAPI BOOL CredUnPackAuthenticationBufferW(
  DWORD  dwFlags,
  PVOID  pAuthBuffer,
  DWORD  cbAuthBuffer,
  LPWSTR pszUserName,
  DWORD  *pcchMaxUserName,
  LPWSTR pszDomainName,
  DWORD  *pcchMaxDomainName,
  LPWSTR pszPassword,
  DWORD  *pcchMaxPassword
);
```

Tham số mà chúng ta cần quan tâm đó là: `pszUserName` và `pszPassword`.

```jsx
var pszUserName, pszPassword, decryptedUsername, decryptedPassword;
var credUnPackAuthenticationBufferW = Module.findExportByName("Credui.dll", "CredUnPackAuthenticationBufferW");

Interceptor.attach(credUnPackAuthenticationBufferW, {
    onEnter: function (args)
	{
        // Credentials here are still encrypted
        pszUserName = args[3];
        pszPassword = args[7];
    },
    
		onLeave: function (result)
		{
        // Credentials are now decrypted
        decryptedUsername = pszUserName.readUtf16String()
        decryptedPassword = pszPassword.readUtf16String()
        if (decryptedUsername && decryptedPassword)
		{
			console.log("\n[*] Intercepted Credentials: ");
			console.log("[+] Username: " + decryptedUsername);
			console.log("[+] Password: " + decryptedPassword);
        }
    }
});
```

Dùng Frida hook vào `Explorer`:

```powershell
$ frida-ps | findstr "explorer"
 6724  explorer.exe

$ frida -l .\hooking\credential_theft.js -p 6724
```

Làm tương tự các bước như trên để nhập `username` và `password`. Sau đó quan sát trên Frida, ta có được thông tin xác thực đã bị chặn bắt:

```powershell
$ frida -l .\hooking\credential_theft.js -p 6724
[Local::PID::6724]->
[*] Intercepted Credentials:
[+] Username: %COMPUTERNAME%\Alice
[+] Password: this_1s_s3cret_passw0rd
```

## 3.4. Remote Debugging/Hooking với Frida

Ở các phần trước chúng ta đã thực hành **Tracing**, **Patching** với **Frida**, tuy nhiên những gì chúng ta làm chỉ là trên một máy (**localhost**). Phần này chúng ta sẽ đi giải một **CrackMe** đơn giản và chương trình CrackMe này sẽ nằm ở một máy tính khác không phải localhost. Để làm được điều này thì máy tính chạy CrackMe kia cần phải chạy **Frida-Server**, chương trình này sẽ chạy lắng nghe trên một **IP:PORT** nào đó và đợi kết nối đến. Từ một máy tính khác sử dụng **Frida-CLI** (Client) để kết nối Server đến thông qua giao thức TCP.

Chương trình **CrackMe** của chúng ta hoạt động như sau: Nhập mật khẩu sau đó kiểm tra nếu đúng thì in ra `Congrats!` còn nếu sai thì in ra `Try again.`

```powershell
$ crackme-101.exe
Enter Password: 123456
Try again.
```

Đầu tiên hãy tải Frida Server ứng với phiên bản Hệ điều hành đang sử dụng tại: https://github.com/frida/frida/releases. Tôi sử dụng **Windows 10 64-bits** nên tôi tải file: `frida-server-<version>-windows-x86_64.exe.xz`. Sau đó khởi chạy Frida-Server trên máy chạy CrackMe: Tham số `-l` chỉ ra địa chỉ ip muốn lắng nghe, có thể lắng nghe trên một interface cụ thể của máy hoặc tất cả các interface:

```powershell
$ frida-server.exe -l 0.0.0.0
```

Kiểm tra lại và đảm bảo rằng **Frida-Server** chắc chẵn đã chạy, nếu có bật tường lửa thì cần cho phép kết nối thông qua **Port 27042** vì đây là Port mặc định của Frida-Server:

```powershell
$ netstat -ano | findstr :27042
  TCP    0.0.0.0:27042          0.0.0.0:0              LISTENING       312
```

```powershell
$ tasklist /fi "pid eq 312"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
frida-server.exe               312 RDP-Tcp#5                  2      7,976 K
```

Kiểm tra chương trình bằng bất kỳ một công cụ nào như: **CFF Explorer, PE-Studio, PE-Bear**,.v.v.. chúng ta đều có thể thấy chương trình này có Import một hàm `strncmp()`. Chúng ta sẽ hook hàm này. Trên một máy tính khác (Client) có cài bộ công cụ `Frida-Tools`. Trước tiên chúng ta thực hiện như sau, để xác nhận rằng chương trình CrackMe có gọi đến hàm `strncmp()`. Trong đó `192.168.40.98` là địa chỉ máy từ xa, còn `C:\Users\Admin\Desktop\Sample\crackme-101.exe` là đường dẫn chương trình muốn chạy.

```powershell
$ frida-trace -i "strncmp" -H 192.168.40.98 C:\Users\Admin\Desktop\Sample\crackme-101.exe
```

Tại máy từ xa lúc này khi kiểm tra bằng Process Explorer chúng ta sẽ thấy CrackMe được Run bởi Frida-Server

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/35ffed0c-8042-4247-a1a7-6545d1dc82b1.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7d405931-779c-483a-9a73-99c3266f3218/Untitled.png align="center")

Trên Console của Frida-Server, nhập mật khẩu sau đó quan sát kết quả:

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/c10b84ed-651c-4478-9056-1bb2d515b8cf.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/66b7d181-27f7-4d6a-a0d2-abf6d94b44cc/Untitled.png align="center")

Quay lại phía client chúng ta thấy hàm strncmp() đã được gọi

```powershell
$ frida-trace -i "strncmp" -H 192.168.40.98 C:\Users\Admin\Desktop\Sample\crackme-101.exe
Instrumenting...
...
Started tracing 3 functions. Press Ctrl+C to stop.
           /* TID 0x2230 */
435830 ms  strncmp()
Process terminated
```

Tiến hành viết Script hook vào hàm `strncmp()`: Xem định định nghĩa hàm này tại: https://www.cplusplus.com/reference/cstring/strncmp/

```jsx
var strncmp = Module.findExportByName("msvcrt.dll", "strncmp");

Interceptor.attach(strncmp, {
    onEnter: function(args)
    {
		console.log("\nstrncmp at: " + strncmp);		
        console.log("  str1: " + Memory.readUtf8String(args[0]));
        console.log("  str2: " + Memory.readUtf8String(args[1]));
        console.log("   num: " + args[2]);
    }
});
```

Trên máy client chạy lại lần 1 và trên máy từ xa nhập mật khẩu là `123456` và quan sát kết quả:

```powershell
$ frida -l .\hooking\apis_hooking_remote.js -H 192.168.40.98 C:\Users\Admin\Desktop\Sample\crackme-101.exe --no-pause
...
[Remote::crackme-101.exe]->
strncmp at: 0x76adac30
  str1: z8dye:Vq9{V:gJ{py}(
  str2: 8;:=<?♥
   num: 0x14
Process terminated
```

Trên máy client chạy lại lần 2 và trên máy từ xa nhập mật khẩu là `abc123` và quan sát kết quả:

```powershell
[Remote::crackme-101.exe]->
strncmp at: 0x76adac30
  str1: z8dye:Vq9{V:gJ{py}(
  str2: hkj8;:♥
   num: 0x14
Process terminated
```

Nhận thấy chuỗi `str1` sau các lần chạy đều không thay đổi, chỉ có dữ liệu nhập tức `str2` là thay đổi, như vậy khả năng dữ liệu nhập của chúng ta phải đi qua một hàm mã hóa nào đó, cuối cùng kết quả mới đem so sánh với chuỗi `str1` là `z8dye:Vq9{V:gJ{py}(`. Lúc này cần một chút kiến thức về Static Code Analysis, sau khi phân tích biết được hàm mã hóa sử dụng phép **XOR** để mã hóa. Nhận thấy đặc điểm của phép XOR gồm 3 toán hạng và nếu đem bất kỳ 2 toán hạng nào trong đó XOR với nhau thì sẽ ra toán hạng còn lại. Như vậy nếu chúng ta nhập chuỗi `str1` của chương trình thì chuỗi `str2` sẽ là mật khẩu cần tìm. Trên máy Remote thực hiện:

```powershell
...
Enter Password: z8dye:Vq9{V:gJ{py}(
Try again.
```

Tại máy client quan sát được:

```powershell
[Remote::crackme-101.exe]->
strncmp at: 0x76adac30
  str1: z8dye:Vq9{V:gJ{py}(
  str2: s1mpl3_x0r_3nCrypt!
   num: 0x14
Process terminated
```

Sử dụng Password tìm được là chuỗi `str2`, để kiểm tra. Kết quả chương trình hiện ra `Congrats!`

```powershell
...
Enter Password: s1mpl3_x0r_3nCrypt!
Congrats!
```

Khi đó trên máy Client quan sát ta sẽ thấy được:

```powershell
[Remote::crackme-101.exe]->
strncmp at: 0x76adac30
  str1: z8dye:Vq9{V:gJ{py}(
  str2: z8dye:Vq9{V:gJ{py}(
   num: 0x14
Process terminated
```

Ngoài ra cũng có cách khác để giải quyết CrackMe này đó là **Memory Patching**, khi hook vào hàm `strncmp()` chúng ta sẽ làm cho điều kiện trả về là 2 chuỗi luôn luôn bằng nhau.

```jsx
var strncmp = Module.findExportByName("msvcrt.dll", "strncmp");

Interceptor.attach(strncmp, {

    onEnter: function(args)
    {
        args[1] = args[0]
		console.log("\nstrncmp at: " + strncmp);		
        console.log("  str1: " + Memory.readUtf8String(args[0]));
        console.log("  str2: " + Memory.readUtf8String(args[1]));
    }
});
```

Lúc này chúng ta nhập bất kỳ mật khẩu nào chương trình vẫn in ra chuỗi `Congrats!`

![](https://cdn.hashnode.com/uploads/covers/6698c3b850049834bdc8b385/dcb4b55b-3b98-4a3c-ad6d-690c0654df18.png align="center")

![](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6a61c8a6-390a-4c37-951f-1cba0c3ff5b1/Untitled.png align="center")

```powershell
$ frida -l .\hooking\apis_hooking_remote.js -H 192.168.40.98 C:\Users\Admin\Desktop\Sample\crackme-101.exe --no-pause
...
Spawned `C:\Users\Admin\Desktop\Sample\crackme-101.exe`. Resuming main thread!
[Remote::crackme-101.exe]->
strncmp at: 0x76adac30
  str1: z8dye:Vq9{V:gJ{py}(
  str2: z8dye:Vq9{V:gJ{py}(
Process terminated
```

# 4\. Tham khảo

*   Instrumenting Windows APIs with Frida - https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/instrumenting-windows-apis-with-frida
    
*   Getting Started with Frida: Hooking a Function and Replacing its Arguments - https://blog.fadyothman.com/getting-started-with-frida-hooking-main-and-playing-with-its-arguments
    
*   Using Frida For Windows Reverse Engineering - https://darungrim.com/research/2020-06-17-using-frida-for-windows-reverse-engineering.html
    
*   3 Ways to Run App as Different User in Windows 10 - https://www.top-password.com/blog/run-app-as-different-user-in-windows-10/
