DLL注入不成功,请教原因!

C/C++ code

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <TlHelp32.h>

using namespace std;

BOOL EnableDebugPriv();
DWORD FindTarget(wchar_t*);

int main()
{
    EnableDebugPriv();

    DWORD dwPID;
    dwPID = FindTarget(L"NOTEPAD.EXE");

    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwPID );

    if( !hProcess )
    {
        return 1;
    }

    // 向目标进程地址空间写入DLL名称
    wchar_t* szDll = L"d:\\test.dll";
    DWORD dwSize, dwWritten;
    dwSize = wcslen(szDll) + 1;

    LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
    
    // 申请内存失败处理
    if ( NULL == lpBuf )
    {
        CloseHandle( hProcess );
        return 1;
    }

    if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)szDll, dwSize, &dwWritten ) )
    {
        //要写入字节数与实际写入字节数不相等 失败处理
        if ( dwWritten != dwSize )
        {
            VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
            CloseHandle( hProcess );
            return 1;
        }
    }
    else
    {
        //改写内存区域 失败处理
        CloseHandle( hProcess );
        return 1;
    }

    DWORD dwID;
    LPVOID pFunc = LoadLibraryW;
    HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );
    
    if( dwID == NULL )
    {
        return 1;
    }

    return 0;
}

BOOL EnableDebugPriv()
{
    typedef int (__stdcall * type_RtlAdjustPrivilege)(int, bool, bool, int*);
    type_RtlAdjustPrivilege RtlAdjustPrivilege = (type_RtlAdjustPrivilege)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlAdjustPrivilege");
    if(RtlAdjustPrivilege == NULL)
    {
        return FALSE;
    }
    int nEn = 0;
    RtlAdjustPrivilege(0x14,TRUE,FALSE,&nEn);
    return TRUE;
}

DWORD FindTarget(wchar_t* ProcessName)
{
    DWORD dwRet = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof( PROCESSENTRY32 );
    Process32First( hSnapshot, &pe32 );
    do
    {
        if ( wcsicmp( pe32.szExeFile, ProcessName) == 0 )
        {
            dwRet = pe32.th32ProcessID;
            break;
        }
    } while ( Process32Next( hSnapshot, &pe32 ) );
    
    CloseHandle( hSnapshot );
    return dwRet;
}



运行后查看进程模块,并没有发现注入的DLL,请教原因!

作者: cnxfmz   发布时间: 2011-06-15

这样也可以调用DLL?我只用过DllImport。

作者: honglian0213   发布时间: 2011-06-15

windows核心编程 + 单步调试 GetLastError

作者: q191201771   发布时间: 2011-06-15

楼主代码使用的远程线程注入记事本程序
应该没有错误 
我在win7下调试通过
你再试下,先打开一个记事本运行程序试下
我这里是注入成功了

作者: evi10r   发布时间: 2011-06-15

我调试NOTEPAD.exe进程,发现写入的字串不对:

Breakpoint 1 hit
eax=00000000 ebx=00be0000 ecx=00ceffb0 edx=7c92e4f4 esi=7c92e4f4 edi=00000f88
eip=7c80aedb esp=00ceffb8 ebp=00ceffec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!LoadLibraryW:
7c80aedb 8bff mov edi,edi
0:001> du poi(esp + 4)
00be0000 "d:\tes"

作者: hiroyukki   发布时间: 2011-06-15

你 WriteProcessMemory时,SIZE不对,你要写的是UNICODE字符。
就是说D:\\test.dll没有写完全。

作者: hiroyukki   发布时间: 2011-06-15

结贴给分。

作者: hiroyukki   发布时间: 2011-06-15

引用 1 楼 honglian0213 的回复:
这样也可以调用DLL?我只用过DllImport。

谢谢提醒!
在书中590页讲到这了一共7个步骤。
其中最后释放内存等我的代码中并没有写,汗!


引用 4 楼 hiroyukki 的回复:
我调试NOTEPAD.exe进程,发现写入的字串不对:

Breakpoint 1 hit
eax=00000000 ebx=00be0000 ecx=00ceffb0 edx=7c92e4f4 esi=7c92e4f4 edi=00000f88
eip=7c80aedb esp=00ceffb8 ebp=00ceffec iopl=0 nv up ei pl zr na ……

感谢指出问题!
的确是这样。应该写成:dwSize = wcslen(szDll) * sizeof(DWORD) + 1;

另外,想问下,我创建的工程默认都是使用Unicode字符集,所以在写代码的时候,容易忘记宽字符带来的一些要注意的地方,如上。
如何来避免这种问题?采用多字符集?

作者: cnxfmz   发布时间: 2011-06-15

引用 2 楼 q191201771 的回复:
windows核心编程 + 单步调试 GetLastError


上面引用错了。可恶的不能编辑!

谢谢提醒!
在书中590页讲到这了一共7个步骤。
其中最后释放内存等我的代码中并没有写,汗!

作者: cnxfmz   发布时间: 2011-06-15

用unicode就要注意unicode的问题。没啥好避免的。

以前一直用多字符集,就导致今天用unicode出了长度的问题。

没事用啥unicode.....搞注入的都是务实派,用得着搞unicode吗。。。。装啥呢~

作者: coding_hello   发布时间: 2011-06-15

引用 7 楼 cnxfmz 的回复:

引用 1 楼 honglian0213 的回复:
这样也可以调用DLL?我只用过DllImport。

谢谢提醒!
在书中590页讲到这了一共7个步骤。
其中最后释放内存等我的代码中并没有写,汗!


引用 4 楼 hiroyukki 的回复:
我调试NOTEPAD.exe进程,发现写入的字串不对:

Breakpoint 1 hit
eax=00000000 ebx=0……

我个人习惯是内部的代码全部使用W的函数,性能损失要小一些。
如果向外提供接口,就简单地实现个A版的函数,调用自己W版的函数。

作者: hiroyukki   发布时间: 2011-06-15