[toc]

使用C语言将动态链接库加载到实验程序后调用汇编Call

1.写一个C语言程序,在程序里通过内联汇编调用C语言函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//Message.c
#include <windows.h>
#include <stdio.h>

void Message()
{
MessageBoxA(NULL, "HellWorld", "Text", MB_OK);
}
void AsmMessage()
{
__asm {
mov edx, 0x00411406 //0x00411406 is Message() address
call edx
}
}
int main(int argc, char** argv)
{
printf("MessageBoxA address is 0x%p\n", &MessageBoxA);
printf("Message() address is 0x%p\n", &Message);
printf("Current pid is %d\n", GetCurrentProcessId());
AsmMessage();
MSG msg;
while (GetMessageW(&msg, NULL, NULL, NULL))
{

}
return 0;
}

2.在Dll文件中 写一个内联汇编程序并使用C语言程序注入到Message.exe中

1.创建一个动态链接库项目

  1. dllmain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// dllmain.c : Defines the entry point for the DLL application.
#include <windows.h>
#include "dllmessage.h"

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DllAsmMessage();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
  1. dllmessage.c
1
2
3
4
5
6
7
8
9
10
#include "dllmessage.h"

void DllAsmMessage()
{
__asm {
mov edx, 0x00411406 //0x00411406 is Message() address
call edx
}
}

  1. dllmessage.h
1
2
3
#pragma once

void DllAsmMessage();
  1. 编译后备用

2. 使用C语言程序将Dll文件加载到Message.exe中

  1. main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//main.c
#include <stdio.h>
#include <Windows.h>

BOOL Load(DWORD dwProcessID, const WCHAR* szPath)
{
//LoadLibrary
//CreateRemoteThread
//1.打开目标进程获取句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
//2.在目标进程体内申请空间
LPVOID lpAddress = VirtualAllocEx(hProcess, NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
//3.写入DLL路径
SIZE_T sWriteLength = 0;
BOOL bRet = WriteProcessMemory(hProcess, lpAddress, szPath, ((wcslen(szPath) + 1) * 2), &sWriteLength);
if (bRet == FALSE)
{
MessageBoxW(NULL, L"WriteProcessMemory Failed!", L"Error", MB_OK);
}
//4.创建远程线程,执行回调
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryW, lpAddress, NULL, NULL);
//5.等待远程线程执行结束(LoadLibrary返回了)
WaitForSingleObject(hThread, INFINITE);
//6.释放空间
VirtualFreeEx(hProcess, lpAddress, 0, MEM_RELEASE);
//7.释放句柄
CloseHandle(hProcess);
CloseHandle(hThread);
//8.返回结果
return TRUE;
}
int main()
{
//传入的两个参数分别为进程id与dll的绝对路径
Load(62648, L"D:\\test\\CC++\\c生万物之windows程序开发\\C+windows\\Debug\\Dll1.dll");
system("pause");
return 0;
}
  1. 运行Message.exe
  2. 运行main.exe
  3. 运行成功后在Message.exe中弹出了一个消息框

在DLL中将C语言代码与汇编代码分开

1.在Dll文件中 写一个内联汇编程序并使用C语言程序注入到Message.exe中

1.创建一个动态链接库项目,将C语言代码与汇编代码分开编写

此种做法需要在项目中勾选masm

  1. dllmain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// dllmain.c : Defines the entry point for the DLL application.
#include <windows.h>

extern int DllAsmMessageA_(void* paddr);

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DllAsmMessageA_(0x00411406);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
  1. dllmessageA。asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;AsmMessage.asm
.586
.model flat,stdcall,c
option casemap:none

.data
.code
DllAsmMessageA_ proc
mov eax,[esp+4]; eax = 'paddr'
call eax
ret
DllAsmMessageA_ endp
end

  1. 编译后备用

2. 使用C语言程序将Dll文件加载到Message.exe中

  1. main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//main.c
#include <stdio.h>
#include <Windows.h>

BOOL Load(DWORD dwProcessID, const WCHAR* szPath)
{
//LoadLibrary
//CreateRemoteThread
//1.打开目标进程获取句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
//2.在目标进程体内申请空间
LPVOID lpAddress = VirtualAllocEx(hProcess, NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
//3.写入DLL路径
SIZE_T sWriteLength = 0;
BOOL bRet = WriteProcessMemory(hProcess, lpAddress, szPath, ((wcslen(szPath) + 1) * 2), &sWriteLength);
if (bRet == FALSE)
{
MessageBoxW(NULL, L"WriteProcessMemory Failed!", L"Error", MB_OK);
}
//4.创建远程线程,执行回调
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryW, lpAddress, NULL, NULL);
//5.等待远程线程执行结束(LoadLibrary返回了)
WaitForSingleObject(hThread, INFINITE);
//6.释放空间
VirtualFreeEx(hProcess, lpAddress, 0, MEM_RELEASE);
//7.释放句柄
CloseHandle(hProcess);
CloseHandle(hThread);
//8.返回结果
return TRUE;
}
int main()
{
//传入的两个参数分别为进程id与dll的绝对路径
Load(62648, L"D:\\test\\CC++\\c生万物之windows程序开发\\C+windows\\Debug\\Dll1.dll");
system("pause");
return 0;
}
  1. 运行Message.exe
  2. 运行main.exe
  3. 运行成功后在Message.exe中弹出了一个消息框