分类:
2008-10-13 16:32:40
题目太罗嗦,不知所云!我先解释一下
<一dll导出一个函数Add,用加壳工具对它进行加壳,加壳时让此加壳工具把原来的导出表hide,现一exe想动态调用加过壳的dll中的Add函数,可以吗?>
动态连接函数的方法: LoadLibrary,GetProcAddress,壳在我们LoadLibrary返回时就把原始文件Fix好在内存中了!
cmpb [esp + 8], 1//是DLL_PROCESS_ATTACH才Fix
jnz reloc_end_jmp
那GetProcAddress可以找到在壳中没导出而在原始文件导出的函数吗?
(Add函数在原始文件中导出了,但加过壳后就被hide了)
代码伺候:(reactos的代码)
GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
{
ANSI_STRING ProcedureName;
FARPROC fnExp = NULL;
if (HIWORD(lpProcName) != 0)
{
RtlInitAnsiString (&ProcedureName,
(LPSTR)lpProcName);
LdrGetProcedureAddress ((PVOID)hModule,
&ProcedureName,
0,
(PVOID*)&fnExp);
}
else
{
LdrGetProcedureAddress ((PVOID)hModule,
NULL,
(ULONG)lpProcName,
(PVOID*)&fnExp);
}
return fnExp;
}
NTSTATUS NTAPI
LdrGetProcedureAddress (IN PVOID BaseAddress,
IN PANSI_STRING Name,
IN ULONG Ordinal,
OUT PVOID *ProcedureAddress)
{
if (Name && Name->Length)
{
TRACE_LDR("LdrGetProcedureAddress by NAME - %Z\n", Name);
}
else
{
TRACE_LDR("LdrGetProcedureAddress by ORDINAL - %d\n", Ordinal);
}
DPRINT("LdrGetProcedureAddress (BaseAddress %p Name %Z Ordinal %lu ProcedureAddress %p)\n",
BaseAddress, Name, Ordinal, ProcedureAddress);
if (Name && Name->Length)
{
/* by name */
*ProcedureAddress = LdrGetExportByName(BaseAddress, (PUCHAR)Name->Buffer, 0xffff);
if (*ProcedureAddress != NULL)
{
return STATUS_SUCCESS;
}
DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
}
else
{
/* by ordinal */
Ordinal &= 0x0000FFFF;
*ProcedureAddress = LdrGetExportByOrdinal(BaseAddress, (WORD)Ordinal);
if (*ProcedureAddress)
{
return STATUS_SUCCESS;
}
DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%lu\n", Ordinal);
}
return STATUS_PROCEDURE_NOT_FOUND;
}
/**********************************************************************
* NAME LOCAL
* LdrGetExportByName
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
* AddressOfNames and AddressOfNameOrdinals are paralell tables,
* both with NumberOfNames entries.
*
*/
static PVOID
LdrGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
WORD Hint)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
PDWORD * ExFunctions;
PDWORD * ExNames;
USHORT * ExOrdinals;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
LONG minn, maxn;
ULONG ExportDirSize;
DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
if (ExportDir == NULL)
{
DPRINT1("LdrGetExportByName(): no export directory!\n");
return NULL;
}
//The symbol names may be missing entirely
if (ExportDir->AddressOfNames == 0)
{
DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
return NULL;
}
/*
* Get header pointers
*/
ExNames = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress,
ExportDir->AddressOfNameOrdinals);
ExFunctions = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfFunctions);
/*
* Check the hint first
*/
if (Hint < ExportDir->NumberOfNames)
{
ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
}
/*
* Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
LONG mid;
LONG res;
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
else if (minn == maxn)
{
DPRINT("LdrGetExportByName(): binary search failed\n");
break;
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
/**********************************************************************
* NAME LOCAL
* LdrGetExportByName
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
* AddressOfNames and AddressOfNameOrdinals are paralell tables,
* both with NumberOfNames entries.
*
*/
static PVOID
LdrGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
WORD Hint)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
PDWORD * ExFunctions;
PDWORD * ExNames;
USHORT * ExOrdinals;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
LONG minn, maxn;
ULONG ExportDirSize;
DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
if (ExportDir == NULL)
{
DPRINT1("LdrGetExportByName(): no export directory!\n");
return NULL;
}
//The symbol names may be missing entirely
if (ExportDir->AddressOfNames == 0)
{
DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
return NULL;
}
/*
* Get header pointers
*/
ExNames = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress,
ExportDir->AddressOfNameOrdinals);
ExFunctions = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfFunctions);
/*
* Check the hint first
*/
if (Hint < ExportDir->NumberOfNames)
{
ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
}
/*
* Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
LONG mid;
LONG res;
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
return Function;
}
else if (minn == maxn)
{
DPRINT("LdrGetExportByName(): binary search failed\n");
break;
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
通过代码可以得出:可以正常调用!
ps:以前发现过有壳可以hide导出表的,但刚才没找到这样的壳了,等会继续找,证明这个结论!