有需要写入文件
的API用于打开和写入文件的文档化API示例是文件打开 -> kernel32.CreateFile 文件写入 -> kernel32!WriteFile
这些 api 需要内核模式转换,它发生在 ntdll.NtCreateFile 和 ntdll!NtWriteFile
您可以在 ollydbg 中使用 ctrl+g 来跟踪这些 api 并在那里设置断点
假设你有一个文件打开一个文件写如下代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void main(void) {
char *foo = "lets open a file and write in it something\n";
FILE *fp =NULL;
if((fp = fopen("c:\\somewrite.text" , "wb")) != NULL) {
fwrite(foo,strlen(foo),1,fp);
printf("we wrote this %s\n" , foo);
fclose(fp);
}
}
在ollydbg v2.0中打开编译好的exe
ctrl+g -> ntdll.NtCreateFile -> follow -> f2-> f9
你应该在这里休息
CPU Stack
Address Comments
ESP ==> ; /RETURN to KERNELBASE.CreateFileW+1D1
ESP+4 ; |Arg1 = 26F614
ESP+8 ; |Arg2 = 40100080
ESP+C ; |Arg3 = 26F5B8
ESP+10 ; |Arg4 = 26F5FC
ESP+14 ; |Arg5 = 0
ESP+18 ; |Arg6 = 80
ESP+1C ; |Arg7 = 3
ESP+20 ; |Arg8 = 5
ESP+24 ; |Arg9 = 60
ESP+28 ; |Arg10 = 0
ESP+2C ; \Arg11 = 0
ZwCreateFile记录为
NTSTATUS ZwCreateFile(
_Out_ PHANDLE FileHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_opt_ PLARGE_INTEGER AllocationSize,
_In_ ULONG FileAttributes,
_In_ ULONG ShareAccess,
_In_ ULONG CreateDisposition,
_In_ ULONG CreateOptions,
_In_opt_ PVOID EaBuffer,
_In_ ULONG EaLength
);
第三个参数是指向_OBJECT_ATTRIBUTES 的指针,它有一个成员 ObjectName,它是一个指向_UNICODE_STRING的指针
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
所以 0x26f5b8 是指向 OBJECT_ATTRIBUTES 的指针
CPU Dump
Address Hex dump ASCII
0026F5B8 18 00 00 00|00 00 00 00|F4 F5 26 00|42 00 00 00| ôõ& B
0026F5C8 00 00 00 00|E0 F5 26 00| àõ&
此结构 0x0026f5f4 的第三个成员是指向 unicode 字符串的指针
CPU Dump
Address Hex dump ASCII
0026F5F4 2A 00 1A 02|88 99 40 00| * ˆ™@
宽字符缓冲区是 0x00409988
CPU Dump
Address Hex dump ASCII
00409988 5C 00 3F 00|3F 00 5C 00|63 00 3A 00|5C 00 73 00| \ ? ? \ c : \ s
00409998 6F 00 6D 00|65 00 77 00|72 00 69 00|74 00 65 00| o m e w r i t e
004099A8 2E 00 74 00|65 00 78 00|74 00 00 00| . t e x t
您可以在转储中使用 follow 来跟踪并找到路径 您可以使用 ctrl+k 查看调用堆栈并定位可能在此之前操作或创建路径的函数
当您在转储窗口type ctrl+g and type in [[[esp+c]+8]+4]
尊重第三个参数 (esp+c) 中破坏此 API 时,您也可以将此快捷方式用于此特定功能,然后尊重第三个成员,然后尊重第二个成员