写文件如下
#include <iostream>
#include <Windows.h>
typedef HANDLE(WINAPI* CreateFileAFunc)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
DWORD MyGetProcAddress(
_In_ HMODULE hModule,
_In_ LPCSTR lpProcName
)
{
PIMAGE_DOS_HEADER pIMAGE_DOS_HEADER = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pIMAGE_NT_HEADERS = (PIMAGE_NT_HEADERS)(pIMAGE_DOS_HEADER->e_lfanew + (DWORD)hModule); //NT头
PIMAGE_EXPORT_DIRECTORY pIMAGE_EXPORT_DIRECTORYRVA = (PIMAGE_EXPORT_DIRECTORY)(pIMAGE_NT_HEADERS->OptionalHeader.DataDirectory[0].VirtualAddress); //导出表项,获得RVA RVA并不是真正的导出表项需要转VA,转VA需要加上image_base(也就是加载地址)
PIMAGE_EXPORT_DIRECTORY pIMAGE_EXPORT_DIRECTORY = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pIMAGE_EXPORT_DIRECTORYRVA + (DWORD)hModule); //这个才是真正的VA,真正的导出表项,因为RVA在内存中是没有的
DWORD ModuleName = pIMAGE_EXPORT_DIRECTORY->Name + (DWORD)hModule;
//可以看到底下地址都需要写成指针形式
DWORD* pAddressOfFunction = (DWORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfFunctions + (DWORD)hModule);
//printf("%s", ModuleName);
DWORD* NameAddress = (DWORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfNames + (DWORD)hModule);
WORD* pAddressOfNameOrdinals = (WORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfNameOrdinals + (DWORD)hModule);
for (size_t i = 0; i < pIMAGE_EXPORT_DIRECTORY->NumberOfNames; i++)
{
DWORD FunNameRVA = NameAddress[i];
char* FunName = (char*)(FunNameRVA + (DWORD)hModule);
if (strcmp(lpProcName, FunName) == 0)
{
return (pAddressOfFunction[pAddressOfNameOrdinals[i]] + (DWORD)hModule);
}
printf("%s\n", FunName);
}
printf("%s\n", ModuleName);
return NULL;
}
int main()
{
std::cout << "Hello World!\n";
// 加载 Kernel32.dll
HMODULE hModule = LoadLibraryA("Kernel32.dll");
if (hModule == NULL) {
printf("Failed to load Kernel32.dll\n");
return 1;
}
// 获取 CreateFileA 函数地址
DWORD p1 = MyGetProcAddress(hModule, "CreateFileA");
if (p1 == 0) {
printf("Failed to get address of CreateFileA\n");
return 1;
}
// 创建函数指针
CreateFileAFunc pCreateFileA = (CreateFileAFunc)p1;
DWORD dwBytesWritten;
const char* lpFileName = "E:\\myfile.txt";
const char* lpData = "Hello, World!";
DWORD dwDataSize = strlen(lpData);
// 调用 CreateFileA 函数
HANDLE hFile = pCreateFileA(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// 写入文件内容
if (WriteFile(hFile, lpData, dwDataSize, &dwBytesWritten, NULL)) {
printf("文件写入成功!\n");
}
else {
printf("写入文件时发生错误!\n");
}
// 关闭文件句柄
CloseHandle(hFile);
}
else
{
printf("创建文件时发生错误!\n");
}
return 0;
}
读文件如下文章来源:https://www.toymoban.com/news/detail-677814.html
#include <iostream>
#include <Windows.h>
typedef HANDLE(WINAPI* CreateFileAFunc)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
DWORD MyGetProcAddress(
_In_ HMODULE hModule,
_In_ LPCSTR lpProcName
)
{
PIMAGE_DOS_HEADER pIMAGE_DOS_HEADER = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pIMAGE_NT_HEADERS = (PIMAGE_NT_HEADERS)(pIMAGE_DOS_HEADER->e_lfanew + (DWORD)hModule); //NT头
PIMAGE_EXPORT_DIRECTORY pIMAGE_EXPORT_DIRECTORYRVA = (PIMAGE_EXPORT_DIRECTORY)(pIMAGE_NT_HEADERS->OptionalHeader.DataDirectory[0].VirtualAddress); //导出表项,获得RVA RVA并不是真正的导出表项需要转VA,转VA需要加上image_base(也就是加载地址)
PIMAGE_EXPORT_DIRECTORY pIMAGE_EXPORT_DIRECTORY = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pIMAGE_EXPORT_DIRECTORYRVA + (DWORD)hModule); //这个才是真正的VA,真正的导出表项,因为RVA在内存中是没有的
DWORD ModuleName = pIMAGE_EXPORT_DIRECTORY->Name + (DWORD)hModule;
//可以看到底下地址都需要写成指针形式
DWORD* pAddressOfFunction = (DWORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfFunctions + (DWORD)hModule);
//printf("%s", ModuleName);
DWORD* NameAddress = (DWORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfNames + (DWORD)hModule);
WORD* pAddressOfNameOrdinals = (WORD*)(pIMAGE_EXPORT_DIRECTORY->AddressOfNameOrdinals + (DWORD)hModule);
for (size_t i = 0; i < pIMAGE_EXPORT_DIRECTORY->NumberOfNames; i++)
{
DWORD FunNameRVA = NameAddress[i];
char* FunName = (char*)(FunNameRVA + (DWORD)hModule);
if (strcmp(lpProcName, FunName) == 0)
{
return (pAddressOfFunction[pAddressOfNameOrdinals[i]] + (DWORD)hModule);
}
printf("%s\n", FunName);
}
printf("%s\n", ModuleName);
return NULL;
}
int main()
{
std::cout << "Hello World!\n";
// 加载 Kernel32.dll
HMODULE hModule = LoadLibraryA("Kernel32.dll");
if (hModule == NULL) {
printf("Failed to load Kernel32.dll\n");
return 1;
}
// 获取 CreateFileA 函数地址
DWORD p1 = MyGetProcAddress(hModule, "CreateFileA");
if (p1 == 0) {
printf("Failed to get address of CreateFileA\n");
return 1;
}
// 创建函数指针
CreateFileAFunc pCreateFileA = (CreateFileAFunc)p1;
DWORD dwBytesRead;
const char* lpFileName = "E:\\myfile.txt";
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
// 调用 CreateFileA 函数
HANDLE hFile = pCreateFileA(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// 读取文件内容
if (ReadFile(hFile, buffer, BUFFER_SIZE - 1, &dwBytesRead, NULL)) {
buffer[dwBytesRead] = '\0'; // 添加字符串结束符
printf("文件内容:\n%s\n", buffer);
}
else {
printf("写入文件时发生错误!\n");
}
// 关闭文件句柄
CloseHandle(hFile);
}
else
{
printf("创建文件时发生错误!\n");
}
return 0;
}
文章来源地址https://www.toymoban.com/news/detail-677814.html
到了这里,关于调用自实现MyGetProcAddress获得CreateFileA函数并调用创建写入文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!