# Replace
khi chạy thử chương trình nó trả ra kq như này

ném file vào ida, đọc code asm và mã giả thêm vào đó đề bài gọi ý về hàm `TlsCallback_0` nên mình có Ctrl+E để tìm hàm

hiểu đơn giản thì `TlsCallback` sẽ được thực hiện trước main entry point của chương trình xem chương trình có đang bị debug hay không. nếu ta ko bypass được hàm này thì khi debug hàm main sẽ chạy không đúng.
để bypass được hàm này mình chỉ cần patch code ở địa chỉ `0x401018` từ jnz -> jz hoặc `75 3E` -> `74 3E` nếu như sửa opcode.
trong hàm `TlsCallback` có những hàm sau:
*`IsDebuggerPresent()`*
Kiểm tra xem chương trình có đang bị debug hay không
*`GetCurrentProcessId()`*
Truy xuất ra mã định dạng của chương trình đang được call
*`OpenProcess()`*
Cú pháp
```
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
```
Các tham số
`[in] dwDesiredAccess`
Sự truy cập vào đối tượng của chương trình. Quyền truy cập này kiểm tra bảo mật bộ mô tả của chương trình. Sẽ có ít nhất 1 thông số thuộc quyền truy cập chương trình
`[in] bInheritHandle`
Nếu giá thông số mang giá trị `TRUE`, các quy trình được tạo bảo chương trình này sẽ thừa hưởng trình xử lý, ngược lại thi không
`[in] dwProcessId`
Mã định dạng của chương trình cần mở hiện tại là `System Idle Process`(0x00000000), hàm lỗi và dòng code cuối là `ERROR_INVALID_PARAMETER`. Nếu chương trình được chỉ định là chương trình của hệ thống hoặc 1 trong các chương trình thuộc `Client Server Run-TIme Sybsystem` (CSRSS), hàm này lỗi và câu lệnh lỗi trả về là `ERROR_ACCESS_DENIED` vì những hạn chế truy cập ngăn chặn mã cấp người dùng mở chúng.
Nếu bạn sử dụng hàm `GetCurrentProcessId` như là 1 argument của hàm này, hãy cân nhắc sử dụng hàm `GetCurrentProcess` thay cho `OpenProcess`, để cải thiện hiệu suất
Khi thực hiện thành công, giá trị trả về là một bộ điều khiển mở cho quy trình đã được chỉ định
Nếu hàm lỗi, giá trị sẽ trả về NULL. Để biết thêm thông tin về lôi, hãy gọi hàm `GetLastError`
*`WriteProcessMemory()`*
Syntax
```
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
```
Các tham số
`[in] hProcess`
Điều khiển sửa đổi vùng nhớ của chương trình. SỰ điều khiển phải có quyền truy cập `PROCESS_VM_WRITE` và `PROCESS_VM_OPERATION` vào chương trình
`[in] lpBaseAddress`
Một con trỏ trỏ tới địa chỉ của base trong chương trình nơi mà dữ liệu được viết. Trước khi data được chuyển đổi, hệ thống xác nhận rằng mọi dữ liệu nằm trong địa chỉ base và vùng nhớ có kích được định sẵn có thể truy cập được để ghi còn nếu nó không thể truy cập được thì hàm lỗi
`[in] lpBuffer`
Một con trỏ trỏ tới bộ nhớ đệm nơi chứa data được ghi trong không gian địa chỉ của chương trình đã được chỉ định
`[in] nSize`
Số byte được ghi cho chương trình được chỉ định
`[out] lpNumberOfBytesWritten`
Một con trỏ trỏ tới biến nhận được số byte được chuyển đến chương trình được chỉ định. Tham số này là tùy chọn. Nếu `lpNumberOfBytesWritten` là NULL, tham số này sẽ bị bỏ qua
Giá trị trả về
Nếu như hàm thành công, giá trị trả về sẽ khác 0
Nếu hàm thất bại, giá trị được trả về là 0. Để có thêm chi tiết lỗi, gọi hàm `GetLastError`. Hàm sẽ xảy ra lỗi nếu như thao tác ghi được yêu cầu đi vào một khu vực của quy trình không thể truy cập được.
tóm lại ở hàm `TslCallback` này, nó sẽ sửa 4 byte ở địa chỉ `loc_4013A2`
đặt 1 breakpoint ở hàm `TslCallback` ta thấy nó sẽ thay đổi hàm encrypt từ `sub_401180` sang `sub_401070`. search gg xem `0x61C88647` là gì thì nhận thấy đây là thuật toán XTEA.
search script rồi sửa lại key và ciphertext thì ta có script sau
```
#include <stdio.h>
#include <stdint.h>
// http://tpforums.org/forum/threads/2158-XTEA-Encryption-Decryption-Code/page4
void process_decrypt(uint32_t *v, uint32_t *k){
uint32_t v0 = v[0], v1 = v[1], i,
delta = 0x61C88647,
sum = 0xC6EF3720;
for(i = 0; i < 32; i++){
v1 -= (k[3] + (v0 >> 5)) ^ (sum + v0) ^ (k[2] + 16 * v0);
v0 -= (k[1] + (v1 >> 5)) ^ (sum + v1) ^ (*k + 16 * v1);
sum += delta;
}
v[0] = v0;
v[1] = v1;
}
void print(uint32_t x){
printf("%c%c%c%c", x&0xFF, (x&0xFF00)>>8,
(x&0xFF0000)>>16, (x&0xFF000000)>>24);
}
int main(){
uint32_t key[]={1265394774, 1886730597, 1799766630, 1278234475};
for(int i=0;i<4;i++){
print(key[i]);
}
printf("\n");
uint32_t matrix[]={
707800089,
39123321,
3597445555,
76906641,
2749913385,
2260564239,
1813185967,
735802878,
1576067246,
2307279752,
1168926259,
2792909978,
};
for(int i=0;i<6;i++){
process_decrypt(matrix+2*i, key);
}
for(int i=0;i<12;i++){
print(matrix[i]);
}
}
```
run script và ta có flag
> PTITCTF{bdc90e23aa0415e94d0ac46a938efcf3}