好友
阅读权限25
听众
最后登录1970-1-1
|
揰掵佲
发表于 2021-3-17 18:01
之前发过一个帖子,是用易语言实现的
调用QQ/TIM算法实现获取当前登陆账号和ClientKey
https://www.52pojie.cn/thread-1037514-1-1.html
最近这段时间呢,一直在搞跨进程调用,经过不断的测试,找到一个稳定跨进程调用的方法,简单明了.易语言比较熟练,代码早已经封装完成,这次用的是C++还是以https://www.52pojie.cn/thread-1037514-1-1.html为例子跨进程取出指定QQ进程的QQ号
先看效果
然后说一下思路
在进程中利用以下代码调用函数,可以达到稳定[Asm] 纯文本查看 复制代码 00000000 55 push ebp
00000001 89E5 mov ebp, esp
00000003 C9 leave
00000004 58 pop eax
00000005 870424 xchg eax, [esp]
00000008 FFE0 jmp eax
0000000A 89EC mov esp, ebp
0000000C 5D pop ebp
0000000D C3 ret
构建的远程调用函数有最大支持15个参数的传递,只支持int类型
[Asm] 纯文本查看 复制代码 /*
* 定义调用函数的代码
* push ebp
* mov ebp,esp
* sub esp,0x3c
* push arg15
* push arg14
* push arg13
* push arg12
* push arg11
* push arg10
* push arg9
* push arg8
* push arg7
* push arg6
* push arg5
* push arg4
* push arg3
* push arg2
* push arg1
* call pCallFun //这里需要注意的是,我们call的是上面的汇编代码,并非指定的函数
* mov dword [resEax],eax
* add esp,0x3c
* mov esp,ebp
* pop ebp
* ret
*/
代码比较粗糙,贴上来
[C++] 纯文本查看 复制代码 void getPushBin(int arg, LPVOID& pShellCode, HANDLE hProcess)
{
if (arg >= -128 && arg <= 127)
{
unsigned char code = { 106 };
WriteProcessMemory(hProcess, pShellCode, &code, 1, NULL);
pShellCode = LPVOID((int)pShellCode + 1);
WriteProcessMemory(hProcess, pShellCode, (LPVOID)arg, 1, NULL);
pShellCode = LPVOID((int)pShellCode + 1);
}
else {
unsigned char code = { 104 };
WriteProcessMemory(hProcess, pShellCode, &code, 1, NULL);
pShellCode = LPVOID((int)pShellCode + 1);
WriteProcessMemory(hProcess, pShellCode, (LPVOID)&arg, 4, NULL);
pShellCode = LPVOID((int)pShellCode + 4);
}
}
void getCallBin(int src, int Dest, LPVOID& pShellCode, HANDLE hProcess)
{
unsigned char code = { 232 };
WriteProcessMemory(hProcess, pShellCode, &code, 1, NULL);
pShellCode = LPVOID((int)pShellCode + 1);
int arg = Dest - src - 5;
WriteProcessMemory(hProcess, pShellCode, (LPVOID)&arg, 4, NULL);
pShellCode = LPVOID((int)pShellCode + 4);
}
void getresEaxBin(int src, LPVOID& pShellCode, HANDLE hProcess)
{
unsigned char code = { 163 };
WriteProcessMemory(hProcess, pShellCode, &code, 1, NULL);
pShellCode = LPVOID((int)pShellCode + 1);
WriteProcessMemory(hProcess, pShellCode, (LPVOID)&src, 4, NULL);
pShellCode = LPVOID((int)pShellCode + 4);
}
int runRemoteFunc(HANDLE hProcess, int pFunc, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0, int arg6 = 0, int arg7 = 0, int arg8 = 0, int arg9 = 0, int arg10 = 0, int arg11 = 0, int arg12 = 0, int arg13 = 0, int arg14 = 0, int arg15 = 0) {
/*
* 定义callFunCode 这个是调用call的代码
00000000 55 push ebp
00000001 89E5 mov ebp, esp
00000003 C9 leave
00000004 58 pop eax
00000005 870424 xchg eax, [esp]
00000008 FFE0 jmp eax
0000000A 89EC mov esp, ebp
0000000C 5D pop ebp
0000000D C3 ret
*/
unsigned char callFunCode[] = { 85, 137, 229, 201, 88, 135, 4, 36, 255, 224, 137, 236, 93, 195 };
SIZE_T codelen = sizeof(callFunCode);
//分配适当内存
LPVOID pCallFun = VirtualAllocEx(hProcess, NULL, codelen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//准备写入代码
bool res = WriteProcessMemory(hProcess, pCallFun, callFunCode, codelen, NULL);
if (!res)
{
//写入失败,释放内存
MessageBox(NULL, L"写入shellCode失败", L"提示", 0);
VirtualFreeEx(hProcess, pCallFun, 0, MEM_RELEASE);
return -1;
}
//分配调用函数的地址
LPVOID pShellCodeStart = VirtualAllocEx(hProcess, NULL, 0x200, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//保存原有地址
LPVOID pShellCode = pShellCodeStart;
//分配返回值地址
LPVOID resEax = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
/*
* 定义调用函数的代码
* push ebp
* mov ebp,esp
* sub esp,0x3c
* push arg15
* push arg14
* push arg13
* push arg12
* push arg11
* push arg10
* push arg9
* push arg8
* push arg7
* push arg6
* push arg5
* push arg4
* push arg3
* push arg2
* push arg1
* call pCallFun
* mov dword [resEax],eax
* add esp,0x3c
* mov esp,ebp
* pop ebp
* ret
*/
unsigned char pfunHead[6] = { 85,137,229,131,236,60 };
codelen = sizeof(pfunHead);
WriteProcessMemory(hProcess, pShellCode, pfunHead, codelen, NULL);
pShellCode = LPVOID((int)pShellCode + codelen);
getPushBin(arg15, pShellCode, hProcess);
getPushBin(arg14, pShellCode, hProcess);
getPushBin(arg13, pShellCode, hProcess);
getPushBin(arg12, pShellCode, hProcess);
getPushBin(arg11, pShellCode, hProcess);
getPushBin(arg10, pShellCode, hProcess);
getPushBin(arg9, pShellCode, hProcess);
getPushBin(arg8, pShellCode, hProcess);
getPushBin(arg7, pShellCode, hProcess);
getPushBin(arg6, pShellCode, hProcess);
getPushBin(arg5, pShellCode, hProcess);
getPushBin(arg4, pShellCode, hProcess);
getPushBin(arg3, pShellCode, hProcess);
getPushBin(arg2, pShellCode, hProcess);
getPushBin(arg1, pShellCode, hProcess);
getCallBin((int)pShellCode, pFunc, pShellCode, hProcess);
getresEaxBin((int)resEax, pShellCode, hProcess);
unsigned char pfunEnd[] = { 131,196,60,137,236,93,195 };
codelen = sizeof(pfunEnd);
WriteProcessMemory(hProcess, pShellCode, pfunEnd, codelen, NULL);
pShellCode = LPVOID((int)pShellCode + codelen);
DWORD Tid;
HANDLE tHandle = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pShellCodeStart, NULL, NULL, &Tid);
if (!tHandle)
{
VirtualFreeEx(hProcess, pCallFun, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, resEax, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pShellCodeStart, 0, MEM_RELEASE);
MessageBox(NULL, L"执行线程失败失败", L"提示", 0);
return -1;
}
WaitForSingleObject(tHandle, -1);
int resa = 0;
ReadProcessMemory(hProcess, resEax, &resa, 4, 0);
VirtualFreeEx(hProcess, pCallFun, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, resEax, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pShellCodeStart, 0, MEM_RELEASE);
return resa;
}
int main()
{
int nRetCode = 0;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, 20368);// 人懒固定了QQ的PID
HMODULE hModule = LoadLibraryW(L"kernel32.dll");
int pGetModuleHandleA = (int)GetProcAddress(hModule, "GetModuleHandleA");
int pGetProcAddress = (int)GetProcAddress(hModule, "GetProcAddress");
unsigned char dllName[] = "KernelUtil.dll";
unsigned char funName[] = "?GetSelfUin@Contact@Util@@YAKXZ";
LPVOID pDllName = VirtualAllocEx(hProcess, NULL, sizeof(dllName), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pDllName, &dllName, sizeof(dllName), 0);
LPVOID pFunName = VirtualAllocEx(hProcess, NULL, sizeof(funName), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pFunName, &funName, sizeof(funName), 0);
int kernelMoudle = runRemoteFunc(hProcess, pGetModuleHandleA, (int)pDllName);
int getUin = runRemoteFunc(hProcess, pGetProcAddress, kernelMoudle, (int)pFunName);
int res = runRemoteFunc(hProcess, getUin);
CloseHandle(hProcess);
cout << "函数执行完毕:结果是\n\r";
cout << res;
cout << "\n\r\n\r";
return nRetCode;
}
其中 以下3个函数是构建汇编代码的,因为,当无参调用时,默认为0 从 unsigned char* 之后会缺少,导致汇编代码错乱,所以分别在函数内部直接写入到内存
[C++] 纯文本查看 复制代码 getPushBin //push xxx
getCallBin //call xxx
getresEaxBin //mov dword [xxx],eax
求指教如何解决,代码比较糙,轻喷
RemoteFunc.zip
(7.86 KB, 下载次数: 12)
|
免费评分
-
查看全部评分
|