我正在按照这个例子编写 c-shellcode。我重复示例中的步骤以填充结构:示例本身:
;IA86 and AMD64
IFDEF _M_IA86
.386
.model flat, stdcall
ENDIF
;set code section .shell
.CODE shell
;data struct
Shell_Static_Data STRUCT
phrase_ldrloaddll db 16 dup(0)
phrase_msgbox db 16 dup(0) //почему byte?
phrase_hello db 16 dup(0)
phrase_hello_title db 16 dup(0)
phrase_user32 dw 16 dup(0)//почему word?
phrase_ntdll dw 16 dup(0)
Shell_Static_Data ENDS
shelldata Shell_Static_Data <"LdrLoadDll", "MessageBoxA", "Hello hacker", "Shellcode", \
{'u', 's', 'e', 'r', '3', '2', '.', 'd', 'l', 'l'}, {'N', 't', 'd', 'l','l', '.', 'd', 'l', 'l'}>
;getting ptr to shelldata struct
IFDEF _M_IA86
get_data_struct_ptr PROC
;delta
call get_delta
get_delta:
pop eax
;calc var
sub eax, 5
sub eax, sizeof shelldata
ret
get_data_struct_ptr ENDP
ELSEIFDEF _M_AMD64
get_data_struct_ptr PROC
;delta
call get_delta
get_delta:
pop rax
;calc var
sub rax, 5
sub rax, sizeof shelldata
ret
get_data_struct_ptr ENDP
ENDIF
END
为什么确切地暴露了 db 或 dw 。这与在 C 结构中声明的数组的大小有什么关系?按照这个汇编代码,编写了一个 C 结构体:
#pragma pack(push, 1)
typedef struct _Shell_Static_Data {
char phrase_ldrloaddll[16];
char phrase_msgbox[16];
char phrase_hello[16];
char phrase_hello_title[16];
wchar_t phrase_user32[16];
wchar_t phrase_ntdll[16];
} Shell_Static_Data, *PShell_Static_Data;
#pragma pack(pop)
extern PShell_Static_Data __stdcall get_data_struct_ptr();
__declspec(noinline) void entry();
void *get_module_base_addr(wchar_t *mod_name);
void *get_proc_addr(void *mod_addr, char *proc_name);
该示例正在运行,并且按照说明运行。
现在我正在根据这个例子编写我的模拟:MASM:
;IA86 and AMD64
IFDEF _M_IA86
.386
.model flat, stdcall
ENDIF
;set code section .shell
.CODE shell
;data struct
Shell_Static_Data STRUCT
phrase_ldrloaddll db 16 dup(0)
phrase_ntdll dw 16 dup(0)
phrase_kernel32 dw 16 dup(0)
phrase_FindFirFil db 16 dup(0)
phrase_FindNexFileA db 16 dup(0)
phrase_DelFilA db 16 dup(0)
phrase_FindCL db 16 dup(0)
phrase_ExPr db 16 dup(0)
phrase_PathM db 42 dup(0) ;не понимаю какое число нужно выставлять, это зависит от размера массива?
;что нужно выбрать db или dw, может dt ? На чём завязан этот выбор?
phrase_path db 38 dup(0)
Shell_Static_Data ENDS
shelldata Shell_Static_Data <"LdrLoadDll", {'N','t','d','l','l','.','d','l','l'},{'K','e','r','n','e','l','3','2','.','d','l','l'},"FindFirstFileA","FindNextFileA","DeleteFileA","FindClose","ExitProcess","C:\\Users\\Documents\\delete\\d*.*","C:\\Users\\Documents\\delete\\">
;getting ptr to shelldata struct
IFDEF _M_IA86
get_data_struct_ptr PROC
;delta
call get_delta
get_delta:
pop eax
;calc var
sub eax, 5
sub eax, sizeof shelldata
ret
get_data_struct_ptr ENDP
ELSEIFDEF _M_AMD64
get_data_struct_ptr PROC
;delta
call get_delta
get_delta:
pop rax
;calc var
sub rax, 5
sub rax, sizeof shelldata
ret
get_data_struct_ptr ENDP
ENDIF
END
在这里,我试图通过与示例类比来写下我的函数和字符串(因为由于直接链接而禁止在教程中使用指针,但在 shellcode 中不允许这样做)我不明白结构字段是用汇编写的:如何理解是否需要db或dw,它后面的数字,它应该是什么以及它取决于什么(可能取决于引号中的字符数?)C中的结构如下所示:
#pragma pack(push, 1)
typedef struct _Shell_Static_Data {
char phrase_ldrloaddll[16];
wchar_t phrase_ntdll[16];
wchar_t phrase_kernel32[16];
char phrase_FindFirFil[16];//findfirstfilea
char phrase_FindNexFileA[16];
char phrase_DelFilA[16];
char phrase_FindCL[16];//findclose
char phrase_ExPr[16];//exitproc
char phrase_PathM[42];//путь с маской
char phrase_path[38];
} Shell_Static_Data, *PShell_Static_Data;
#pragma pack(pop)
extern PShell_Static_Data __stdcall get_data_struct_ptr();
__declspec(noinline) void entry();
设置当前设置后,VS 说:
A2041 字符串或文本文字太长
(shellcode_native.asm)
A2006 未定义符号:shelldata
帮助解决错误
这里:
必须写出绝对路径
C:\Users\Documents\delete\
,而不是两个斜线