DLL to C: 能把DLL转换成可编译的C代码的工具

最近发现一个好屌的工具DLL to C.。声称能够把DLL转换成可编译的C或C++代码。 我下载试用了一下,居然真的可以。



点击"Start Convert"生成了下面的文件:


打开例子中的工程文件TestWin32Dll.sln,编译运行后弹出一个显示"Hello World!"的消息框。

打开文件Win32Dll.cpp,查看一下它生成的代码:

/*******************************************************************************
	Generated by: DLL to C version 2.18
	Date: 2016-11-29
	Description: The implementation code for Win32Dll.dll.
	Website: http://www.dll-decompiler.com
	Technical Support: support@dll-decompiler.com
*******************************************************************************/

#include "stdafx.h"
#include "Win32Dll.h"


static HMODULE g_hMoudle;
BOOL (WINAPI *Win32Dll_DllEntryPoint)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);

void* __stdcall Win32Dll_RVA(DWORD rvaAddr)
{
	if(rvaAddr==0)
		return g_hMoudle;
	if(rvaAddr >= 0x1000 && rvaAddr < 0x8000)
		return &Win32Dll_text[rvaAddr - 0x1000];
	if(rvaAddr >= 0x8000 && rvaAddr < 0xA000)
		return &Win32Dll_rdata[rvaAddr - 0x8000];
	if(rvaAddr >= 0xA000 && rvaAddr < 0xC000)
		return &Win32Dll_data[rvaAddr - 0xA000];
	return NULL;
}

BOOL Win32Dll_Init()
{
	HMODULE hDll;
	DWORD oldProtect;
	void (*fInitData)(HMODULE,void*);

	g_hMoudle = GetModuleHandle(0);

	oldProtect = PAGE_EXECUTE_READWRITE;
	VirtualProtect(Win32Dll_text,sizeof(Win32Dll_text),PAGE_EXECUTE_READWRITE,&oldProtect);

	hDll = ::LoadLibraryA("USER32.dll");
	if(!hDll)
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80EC) = ::GetProcAddress(hDll,"MessageBoxA");
	if(!*(FARPROC*)Win32Dll_RVA(0x80EC))
		return FALSE;

	hDll = ::LoadLibraryA("KERNEL32.dll");
	if(!hDll)
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8000) = ::GetProcAddress(hDll,"GetTickCount");
	if(!*(FARPROC*)Win32Dll_RVA(0x8000))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8004) = ::GetProcAddress(hDll,"GetCurrentThreadId");
	if(!*(FARPROC*)Win32Dll_RVA(0x8004))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8008) = ::GetProcAddress(hDll,"GetCommandLineA");
	if(!*(FARPROC*)Win32Dll_RVA(0x8008))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x800C) = ::GetProcAddress(hDll,"TerminateProcess");
	if(!*(FARPROC*)Win32Dll_RVA(0x800C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8010) = ::GetProcAddress(hDll,"GetCurrentProcess");
	if(!*(FARPROC*)Win32Dll_RVA(0x8010))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8014) = ::GetProcAddress(hDll,"UnhandledExceptionFilter");
	if(!*(FARPROC*)Win32Dll_RVA(0x8014))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8018) = ::GetProcAddress(hDll,"SetUnhandledExceptionFilter");
	if(!*(FARPROC*)Win32Dll_RVA(0x8018))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x801C) = ::GetProcAddress(hDll,"IsDebuggerPresent");
	if(!*(FARPROC*)Win32Dll_RVA(0x801C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8020) = ::GetProcAddress(hDll,"GetModuleHandleW");
	if(!*(FARPROC*)Win32Dll_RVA(0x8020))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8024) = ::GetProcAddress(hDll,"GetProcAddress");
	if(!*(FARPROC*)Win32Dll_RVA(0x8024))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8028) = ::GetProcAddress(hDll,"TlsGetValue");
	if(!*(FARPROC*)Win32Dll_RVA(0x8028))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x802C) = ::GetProcAddress(hDll,"TlsAlloc");
	if(!*(FARPROC*)Win32Dll_RVA(0x802C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8030) = ::GetProcAddress(hDll,"TlsSetValue");
	if(!*(FARPROC*)Win32Dll_RVA(0x8030))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8034) = ::GetProcAddress(hDll,"TlsFree");
	if(!*(FARPROC*)Win32Dll_RVA(0x8034))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8038) = ::GetProcAddress(hDll,"InterlockedIncrement");
	if(!*(FARPROC*)Win32Dll_RVA(0x8038))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x803C) = ::GetProcAddress(hDll,"SetLastError");
	if(!*(FARPROC*)Win32Dll_RVA(0x803C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8040) = ::GetProcAddress(hDll,"GetLastError");
	if(!*(FARPROC*)Win32Dll_RVA(0x8040))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8044) = ::GetProcAddress(hDll,"InterlockedDecrement");
	if(!*(FARPROC*)Win32Dll_RVA(0x8044))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8048) = ::GetProcAddress(hDll,"HeapFree");
	if(!*(FARPROC*)Win32Dll_RVA(0x8048))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x804C) = ::GetProcAddress(hDll,"Sleep");
	if(!*(FARPROC*)Win32Dll_RVA(0x804C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8050) = ::GetProcAddress(hDll,"ExitProcess");
	if(!*(FARPROC*)Win32Dll_RVA(0x8050))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8054) = ::GetProcAddress(hDll,"SetHandleCount");
	if(!*(FARPROC*)Win32Dll_RVA(0x8054))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8058) = ::GetProcAddress(hDll,"GetStdHandle");
	if(!*(FARPROC*)Win32Dll_RVA(0x8058))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x805C) = ::GetProcAddress(hDll,"GetFileType");
	if(!*(FARPROC*)Win32Dll_RVA(0x805C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8060) = ::GetProcAddress(hDll,"GetStartupInfoA");
	if(!*(FARPROC*)Win32Dll_RVA(0x8060))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8064) = ::GetProcAddress(hDll,"DeleteCriticalSection");
	if(!*(FARPROC*)Win32Dll_RVA(0x8064))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8068) = ::GetProcAddress(hDll,"GetModuleFileNameA");
	if(!*(FARPROC*)Win32Dll_RVA(0x8068))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x806C) = ::GetProcAddress(hDll,"FreeEnvironmentStringsA");
	if(!*(FARPROC*)Win32Dll_RVA(0x806C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8070) = ::GetProcAddress(hDll,"GetEnvironmentStrings");
	if(!*(FARPROC*)Win32Dll_RVA(0x8070))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8074) = ::GetProcAddress(hDll,"FreeEnvironmentStringsW");
	if(!*(FARPROC*)Win32Dll_RVA(0x8074))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8078) = ::GetProcAddress(hDll,"WideCharToMultiByte");
	if(!*(FARPROC*)Win32Dll_RVA(0x8078))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x807C) = ::GetProcAddress(hDll,"GetEnvironmentStringsW");
	if(!*(FARPROC*)Win32Dll_RVA(0x807C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8080) = ::GetProcAddress(hDll,"HeapCreate");
	if(!*(FARPROC*)Win32Dll_RVA(0x8080))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8084) = ::GetProcAddress(hDll,"HeapDestroy");
	if(!*(FARPROC*)Win32Dll_RVA(0x8084))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8088) = ::GetProcAddress(hDll,"VirtualFree");
	if(!*(FARPROC*)Win32Dll_RVA(0x8088))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x808C) = ::GetProcAddress(hDll,"QueryPerformanceCounter");
	if(!*(FARPROC*)Win32Dll_RVA(0x808C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8090) = ::GetProcAddress(hDll,"GetCurrentProcessId");
	if(!*(FARPROC*)Win32Dll_RVA(0x8090))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8094) = ::GetProcAddress(hDll,"GetSystemTimeAsFileTime");
	if(!*(FARPROC*)Win32Dll_RVA(0x8094))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x8098) = ::GetProcAddress(hDll,"LeaveCriticalSection");
	if(!*(FARPROC*)Win32Dll_RVA(0x8098))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x809C) = ::GetProcAddress(hDll,"EnterCriticalSection");
	if(!*(FARPROC*)Win32Dll_RVA(0x809C))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80A0) = ::GetProcAddress(hDll,"GetCPInfo");
	if(!*(FARPROC*)Win32Dll_RVA(0x80A0))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80A4) = ::GetProcAddress(hDll,"GetACP");
	if(!*(FARPROC*)Win32Dll_RVA(0x80A4))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80A8) = ::GetProcAddress(hDll,"GetOEMCP");
	if(!*(FARPROC*)Win32Dll_RVA(0x80A8))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80AC) = ::GetProcAddress(hDll,"IsValidCodePage");
	if(!*(FARPROC*)Win32Dll_RVA(0x80AC))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80B0) = ::GetProcAddress(hDll,"HeapAlloc");
	if(!*(FARPROC*)Win32Dll_RVA(0x80B0))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80B4) = ::GetProcAddress(hDll,"VirtualAlloc");
	if(!*(FARPROC*)Win32Dll_RVA(0x80B4))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80B8) = ::GetProcAddress(hDll,"HeapReAlloc");
	if(!*(FARPROC*)Win32Dll_RVA(0x80B8))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80BC) = ::GetProcAddress(hDll,"WriteFile");
	if(!*(FARPROC*)Win32Dll_RVA(0x80BC))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80C0) = ::GetProcAddress(hDll,"LoadLibraryA");
	if(!*(FARPROC*)Win32Dll_RVA(0x80C0))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80C4) = ::GetProcAddress(hDll,"InitializeCriticalSectionAndSpinCount");
	if(!*(FARPROC*)Win32Dll_RVA(0x80C4))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80C8) = ::GetProcAddress(hDll,"RtlUnwind");
	if(!*(FARPROC*)Win32Dll_RVA(0x80C8))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80CC) = ::GetProcAddress(hDll,"GetLocaleInfoA");
	if(!*(FARPROC*)Win32Dll_RVA(0x80CC))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80D0) = ::GetProcAddress(hDll,"GetStringTypeA");
	if(!*(FARPROC*)Win32Dll_RVA(0x80D0))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80D4) = ::GetProcAddress(hDll,"MultiByteToWideChar");
	if(!*(FARPROC*)Win32Dll_RVA(0x80D4))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80D8) = ::GetProcAddress(hDll,"GetStringTypeW");
	if(!*(FARPROC*)Win32Dll_RVA(0x80D8))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80DC) = ::GetProcAddress(hDll,"LCMapStringA");
	if(!*(FARPROC*)Win32Dll_RVA(0x80DC))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80E0) = ::GetProcAddress(hDll,"LCMapStringW");
	if(!*(FARPROC*)Win32Dll_RVA(0x80E0))
		return FALSE;
	*(FARPROC*)Win32Dll_RVA(0x80E4) = ::GetProcAddress(hDll,"HeapSize");
	if(!*(FARPROC*)Win32Dll_RVA(0x80E4))
		return FALSE;

	*(FARPROC*)&fInitData = (FARPROC)&Win32Dll_InitData[0];
	fInitData(LoadLibraryA("KERNEL32.dll"),Win32Dll_RVA);

	VirtualProtect(Win32Dll_text,sizeof(Win32Dll_text),oldProtect,NULL);

	*(FARPROC*)&Win32Dll_DllEntryPoint = (FARPROC)Win32Dll_RVA(0x1263);
	return TRUE;
}

BOOL Win32Dll_LoadLibrary()
{
	return Win32Dll_DllEntryPoint(GetModuleHandle(0), DLL_PROCESS_ATTACH, 0);
}

BOOL Win32Dll_FreeLibrary()
{
	return Win32Dll_DllEntryPoint(GetModuleHandle(0), DLL_PROCESS_DETACH, 0);
}

FARPROC Win32Dll_GetProcAddress(LPCSTR lpProcName)
{
	if(lstrcmpA(lpProcName,"TestFun")==0)
		return (FARPROC)Win32Dll_RVA(0x1010);

	return NULL;
}

可以看出这个工具把一个DLL的每个Section都分割开了,通过函数Win32Dll_RVA可以访问DLL中的任意地址。通过这个工具,可以把DLL嵌入到主程序中,在安装包中可以不用再包含相应的DLL文件。如果觉得有用的话,可以从他们的官方网站下载: Dll Decompiler

一、简介   AheadLib 是用来生成一个特洛伊DLL工具,用于分析DLL中的函数参数调用(比如记录Socket send了什么等等)、更改函数功能(随心所欲了:)、更改界面功能(比如在Hook里面生成一个按钮,截获事件等等)。 二、使用   1.用 AheadLib 打开要模拟的 DLL,生成一个 CPP 文件。   2.用 Visual Studio 6.0/.NET 建立一个 DLL 工程,把这个 CPP 文件加入到项目中。   3.使用 Release 方式编译,生成的 DLL 将和原来的 DLL 具有一模一样的导出函数,并且能顺利把这些函数转发到原来的函数中。   4.AheadLib 还可以生成 Hook 代码,用于截取当前进程的所有消息,这样就可以随心所欲地处理各种消息了 (修改第三方程序界面功能的好助手)。 三、备注   1.如果导出函数过多,在 Visual Studio 6.0 中,如果出现编译错误,请在项目属性关闭与编译头功能。   2.如果是 C++ 、C __stdcall、C __fastcall 的方式导出的话,生成的函数声明将会还原成原代码级别(可能需要修改才能编译,比如导出C++类的情况)。此时使用 __declspec(dllexport) 导出 ——不能指定导出序号。   3.如果是 NONAME 或者 C _CDECL 方式导出(比如 DEF 导出,大多数Windows DLL都是这种情况,比如WS2_32等等),则使用#pragma comment(linker, "/EXPORT:...)导出,且指定导出序号。   4.如果系统中没有 DbgHelp.dll,将无法识别 C++ 模式的导出。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值