huangchao209 发表于 2014-12-23 22:22:34

还是LdrloadDll 函数的问题

本帖最后由 huangchao209 于 2014-12-23 22:24 编辑

不知道为什么,对微软这个 未公开 LdrloadDll 函数使用搞不懂
之前弄个Delphi 的HOOK 这个函数搞不定,今天再试用C 写的 调用Ldrloaddll 加载 DLL 也没成功
VC 6编译器
现在请老大帮忙看看什么问题

上代码#include <stdio.h>
#include <windows.h>

typedef struct _UNICODE_STRING
{
        USHORT Length;
        USHORT MaximumLength;
        PWSTR Buffer;
} UNICODE_STRING , *PUNICODE_STRING;

typedef ULONG NTSTATUS ;

typedef struct _LDR_DATA_TABLE_ENTRY
{
        LIST_ENTRY InLoadOrderLinks;
        LIST_ENTRY InMemoryOrderModuleList;
        LIST_ENTRY InInitializationOrderModuleList;
        PVOID DllBase;
        PVOID EntryPoint;
        ULONG SizeOfImage;
        UNICODE_STRING FullDllName;
        UNICODE_STRING BaseDllName;
        ULONG Flags;
        USHORT LoadCount;
        USHORT TlsIndex;
        union
        {
                LIST_ENTRY HashLinks;
                PVOID SectionPointer;
        };
        ULONG CheckSum;
        union
        {
                ULONG TimeDateStamp;
                PVOID LoadedImports;
        };
        PVOID EntryPointActivationContext;
        PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB_LDR_DATA {
        ULONG                   Length;
        BOOLEAN               Initialized;
        PVOID                   SsHandle;
        LIST_ENTRY            InLoadOrderModuleList;          //按加载顺序
        LIST_ENTRY            InMemoryOrderModuleList;      //按内存顺序
        LIST_ENTRY            InInitializationOrderModuleList;//按初始化顺序
        PVOID          EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

//每个模块信息的LDR_MODULE部分
typedef struct _LDR_MODULE {
        LIST_ENTRY            InLoadOrderModuleList;         
        LIST_ENTRY            InMemoryOrderModuleList;      
        LIST_ENTRY            InInitializationOrderModuleList;
        PVOID                   BaseAddress;
        PVOID                   EntryPoint;
        ULONG                   SizeOfImage;
        UNICODE_STRING          FullDllName;
        UNICODE_STRING          BaseDllName;
        ULONG                   Flags;
        SHORT                   LoadCount;
        SHORT                   TlsIndex;
        LIST_ENTRY            HashTableEntry;
        ULONG                   TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;

VOID HideModule(HMODULE hLibrary)
{
        PPEB_LDR_DATA        pLdr = NULL;
        PLDR_MODULE                FirstModule = NULL;
        PLDR_MODULE                GurrentModule = NULL;
        __try
        {
                __asm
                {
                        mov esi, fs:
                        mov esi,
                        mov pLdr,esi
                }

                FirstModule = (PLDR_MODULE)(pLdr->InLoadOrderModuleList.Flink);
                GurrentModule = FirstModule;
                while(!(GurrentModule ->BaseAddress == hLibrary))
                {
                        GurrentModule = (PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink);
                        if(GurrentModule == FirstModule)
                                break;
                }
                if(GurrentModule->BaseAddress != hLibrary)
                        return;

                //Dll解除链接
                ((PLDR_MODULE)(GurrentModule -> InLoadOrderModuleList.Flink))->InLoadOrderModuleList.Blink = GurrentModule -> InLoadOrderModuleList.Blink;
                ((PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink))->InLoadOrderModuleList.Flink = GurrentModule->InLoadOrderModuleList.Flink;
               
                memset(GurrentModule->FullDllName.Buffer, 0, GurrentModule->FullDllName.Length);
                memset(GurrentModule, 0, sizeof(PLDR_MODULE));
        }

        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                return;
        }
}

//LdrLoadDll function prototype
typedef NTSTATUS (WINAPI *fLdrLoadDll)(IN PWCHAR PathToFile OPTIONAL,IN ULONG Flags OPTIONAL,IN PUNICODE_STRING ModuleFileName,OUT PHANDLE ModuleHandle);

//RtlInitUnicodeString function prototype
typedef VOID (WINAPI *fRtlInitUnicodeString)(PUNICODE_STRING DestinationString,PCWSTR SourceString);

HMODULE                                        hntdll = NULL;
fLdrLoadDll                                _LdrLoadDll = NULL;
fRtlInitUnicodeString        _RtlInitUnicodeString = NULL;

HMODULE LoadDll(LPCSTR lpFileName)
{
    if (hntdll == NULL)
        {
                hntdll = GetModuleHandleA("ntdll.dll");
                printf("hntdll Handle %x\n",hntdll);
        }

    if (_LdrLoadDll == NULL)
        {
                _LdrLoadDll = (fLdrLoadDll)GetProcAddress (hntdll,"LdrLoadDll");
                printf("_LdrLoadDll Handle %x\n",_LdrLoadDll);
        }

    if (_RtlInitUnicodeString == NULL)
    {
                _RtlInitUnicodeString = (fRtlInitUnicodeString)GetProcAddress (hntdll,"RtlInitUnicodeString");
                printf("_RtlInitUnicodeString Handle %x\n",_RtlInitUnicodeString);
        }
       
    int StrLen = lstrlenA(lpFileName);
    BSTR WideStr = SysAllocStringLen(NULL, StrLen);
    MultiByteToWideChar(CP_ACP, 0, lpFileName, StrLen, WideStr, StrLen);
       
    UNICODE_STRING usDllName = { 0 };
    _RtlInitUnicodeString(&usDllName, WideStr);
    SysFreeString(WideStr);
       
    HANDLE DllHandle = NULL;
    _LdrLoadDll(0, 0, &usDllName, &DllHandle);
       
    return (HMODULE)DllHandle;
}

int main()
{
        HMODULE hMydll = LoadDll("C:\Users\Administrator\Desktop\DELPHI DEMO\重载NTDLL\Test.dll");
       
        printf("hmydll Handle %x\n",hMydll);
        printf("Test.dll Handle %x\n", GetModuleHandleA("Test.dll"));
        //HideModule(hMydll);
        MessageBox(NULL,"Hello",NULL,NULL);
        return 0;
}

Tesla.Angela 发表于 2014-12-24 11:09:38

我也不懂。。。有好好的LoadLibrary不用非要用LdrloadDll。。。
这种找虐的事情我是懒的看的。

不过如果你的代码确定没问题,可能是你路径的问题。这种API应该是用NT路径的:\??\c:\xxx.exe

还有,你这么隐藏DLL没用的,内核里还有一份数据。你这么隐藏,在ARK里只能让你的DLL更加显眼。

huangchao209 发表于 2014-12-24 15:11:00

Tesla.Angela 发表于 2014-12-24 11:09
我也不懂。。。有好好的LoadLibrary不用非要用LdrloadDll。。。
这种找虐的事情我是懒的看的。



受教了,不过,我弄成功了
调用原始 NTDLL 里面 ldrloaddll 可以用
不过不正常调用 重载NTDLL 里面的LdrloadDll 函数
同样的函数 指针 如果调用原始的 ntdll 没问题,调用自己重载的就无法调用

问了下人,人家说重载的dll 不能用 GetProcAddress 获得函数地址,要获得dll的输出表地址才行
不知道是不是

huangchao209 发表于 2014-12-24 15:12:32

Tesla.Angela 发表于 2014-12-24 11:09
我也不懂。。。有好好的LoadLibrary不用非要用LdrloadDll。。。
这种找虐的事情我是懒的看的。



LoadLiibray 虽然调用简单,但是很多都不用这个函数 来加载DLL 直接用更底层 LdrloadDll 注入

Tesla.Angela 发表于 2014-12-24 15:16:29

RE: 还是LdrloadDll 函数的问题

huangchao209 发表于 2014-12-24 15:11
问了下人,人家说重载的dll 不能用 GetProcAddress 获得函数地址,要获得dll的输出表地址才行
不知道是不是

没这一说。还有。如果你真想拦截DLL注入进程,更加靠谱的是在LoadImageNotify里做。

huangchao209 发表于 2014-12-25 14:43:50

Tesla.Angela 发表于 2014-12-24 15:16
没这一说。还有。如果你真想拦截DLL注入进程,更加靠谱的是在LoadImageNotify里做。 ...

不过,在重载的ntdllL里面,无法正常调用里面的函数,现在搜索不到想要资料,我只知道有这种方法
页: [1]
查看完整版本: 还是LdrloadDll 函数的问题