技术开发 频道

Eclipse发布开源软件开发平台

    具体实现过程 

    添加需要使用的全局字符串,定义如下:

char *key1="Software\\abc\\def";
char *key2="InstallCode"; 

    由于DEBUG模式VC默认为函数生成了保护寄存器的代码,总共对4个寄存器进行了保护,因此我们在函数的入口处平衡堆栈,代码如下:
__asm
{
pop edi

pop esi

pop ebx

pop ebp

    如果是RELEASE模式,则只对3个寄存器进行了压栈保护,因此我们在函数的入口处平衡堆栈,两种模式可以合成写成如下的方式: 

//还原堆栈,VC为函数默认生成了保护寄存器的代码

#ifdef _DEBUG //DEBUG模式和RELEASE模式生成的保护寄存器的代码不一样

__asm
{
pop edi

pop esi

pop ebx

pop ebp
}

#else
__asm
{
pop edi

pop esi

pop ebp
}

#endif 

    上面的一段代码,可以使用在函数前面加上__declspec( naked )的方法来替代。

    移植的部分代码加到上面的代码后面即可,具体修改如下:

__asm
{
sub esp, 0x10

lea eax, dword ptr [esp]

push esi
push edi
xor edi, edi
push edi
push eax
push edi
push 0x0F003F
push edi
push edi
push edi

push key1 //如果是指针直接使用指针名称,否则使用lea eax, key1; push eax方式

push 0x80000002

call dword ptr [RegCreateKeyExA] //此处不能使用call RegCreateKeyExA,只能进行间接寻址调用

test eax, eax

jnz short  A10002300 //使用标签让VC自动计算偏移地址,不能使用纯数组标签

mov esi, dword ptr [esp+0x24]

mov eax, key2

mov ecx, [eax]

mov edx, [eax+4]

mov eax, [eax+8]

test esi, esi

mov dword ptr [esp+0x0C], ecx
mov dword ptr [esp+0x10], edx
mov dword ptr [esp+0x14], eax

je short  A10002300  //使用标签让VC自动计算偏移地址


push esi

call dword ptr [lstrlenA]  //此处不能使用call lstrlenA,只能进行间接寻址调用

inc eax

lea ecx, dword ptr [esp+0x0C]

mov edx, dword ptr [esp+0x08]

push eax
push esi
push 1
push edi
push ecx
push edx

call dword ptr [RegSetValueExA] //此处不能使用call RegSetValueExA,只能进行间接寻址调用


test eax, eax

jnz short A100022F5

mov edi, 1

A100022F5:

mov eax, dword ptr [esp+0x08]
push eax

call dword ptr [RegCloseKey] //此处不能使用call RegCloseKey,只能进行间接寻址调用

A10002300:

mov eax, edi
pop edi
pop esi
add esp, 0x10

retn 0x0c
}


全部源代码如下:

// PCInfoAPI.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

#define PCInfoAPI_EXPORTS

#ifdef PCInfoAPI_EXPORTS

#define PCInfoAPI_API extern "C" __declspec(dllexport)
#else
#define PCInfoAPI_API __declspec(dllimport)
#endif

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}


char *key1="Software\\abc\\def";

char *key2="InstallCode";


PCInfoAPI_API int __stdcall RegistryCode(int a1,int a2,const char * key)
{
//还原堆栈,VC为函数默认生成了保护寄存器的代码

#ifdef _DEBUG //DEBUG模式和RELEASE模式生成的保护寄存器的代码不一样

__asm
{
pop edi

pop esi

pop ebx

pop ebp
}

#else
__asm
{
pop edi

pop esi

pop ebp
}

#endif


__asm
{
sub esp, 0x10

lea eax, dword ptr [esp]

push esi
push edi
xor edi, edi
push edi
push eax
push edi
push 0x0F003F
push edi
push edi
push edi

push key1

push 0x80000002

call dword ptr [RegCreateKeyExA]

test eax, eax

jnz short A10002300

mov esi, dword ptr [esp+0x24]

//mov esi, key

mov eax, key2

mov ecx, [eax]

mov edx, [eax+4]

mov eax, [eax+8]

test esi, esi

mov dword ptr [esp+0x0C], ecx
mov dword ptr [esp+0x10], edx
mov dword ptr [esp+0x14], eax

je short A10002300

push esi

call dword ptr [lstrlenA]

inc eax

lea ecx, dword ptr [esp+0x0C]

mov edx, dword ptr [esp+0x08]

push eax
push esi
push 1
push edi
push ecx
push edx

call dword ptr [RegSetValueExA]

test eax, eax

jnz short A100022F5

mov edi, 1

A100022F5:

mov eax, dword ptr [esp+0x08]
push eax

call dword ptr [RegCloseKey]

A10002300:

mov eax, edi
pop edi
pop esi
add esp, 0x10

retn 0x0c
}

}


0
相关文章