这是我用来中止一个进程的模块的代码。
问题是:
1、这样中止进程的模块是否正确?
2、用这样的方法,在FreeLibrary(me32.hModule)成功后,再对进程的模块作快照,发现模块还在,是否中止成功了?
3、如果中止成功了,怎样才能在快照中不显示?
/*! @function
********************************************************************************
函数名   : StopModules
功能     : 中止进程的模块
参数     : 
返回值   : 
抛出异常 : 
*******************************************************************************/
void StopModule()
{
   ListView::SelectedListViewItemCollection^ breakfast = this->lstModule->SelectedItems;              
   System::Collections::IEnumerator^ myEnum = breakfast->GetEnumerator();   while ( myEnum->MoveNext() )
   {
      ListViewItem^ item = safe_cast<ListViewItem^>(myEnum->Current);
      pin_ptr<const wchar_t> wch = PtrToStringChars(item->Text);      //************************************************
      HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
      MODULEENTRY32 me32;      // 对指定进程的所有模块快照.
      hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, this->curProcessID );      //快照失败,退出
      if( hModuleSnap  == INVALID_HANDLE_VALUE )
      {
         return/*( FALSE )*/;
      }      // 结构体使用前设置大小.
      me32.dwSize = sizeof( MODULEENTRY32 );      // 检索首个模块信息,如果不成功就退出
      if( !Module32First( hModuleSnap, &me32 ) )
      {
         CloseHandle( hModuleSnap );     // 退出前必须清理对象!
                     //return( FALSE );
      }      //遍历进程的模块列表,显示每个信息
      do
      {
         if(wcscmp(me32.szModule, wch) == 0 )
         {
            if(!FreeLibrary(me32.hModule))
               ::MessageBox(NULL, L"", L"", MB_OK);
            CloseHandle( hModuleSnap );
            //return( TRUE );
            break;
         }
      } while( Module32Next( hModuleSnap, &me32 ) );      CloseHandle( hModuleSnap );
      //********************************************
      delete[] item;
    }}

解决方案 »

  1.   

    进程的模块,指的dll吗?从上面的代码来看FreeLibrary会应该重新取一次快照,再判断。
      

  2.   

    FreeLibrary 只是减一次 模块引用计数. 只有引用计数<=0时才卸载dll
      

  3.   

    Decrements the reference count of the loaded dynamic-link library (DLL). When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.
      

  4.   


    while(...)
    {
    StopModule();
    }
      

  5.   

    直接用NtUnmapViewOfSection把模块卸了
      

  6.   

    NtUnmapViewOfSection?
    我查下用法
      

  7.   

    你这样做
    先通过模块基地址找到dllmain地址,再使用DLL_PROCESS_DETACH调用dllmain
    然后把PPEB_LDR_DATA Ldr;中的链表中的该模块项移除
    最后用NtUnmapViewOfSection撤销模块section的映射
      

  8.   

    列宁同志
    能不能给我个示例?
    我用的的VS2005,没有NtUnmapViewOfSection这个东东。
    谢谢。
      

  9.   

    你可以找一个ntdll.lib,然后自己声明
    或者
    typedef ULONG_PTR(__stdcall*TNtUnmapViewOfSection)(void*,void*);
    TNtUnmapViewOfSection NtUnmapViewOfSection;
    NtUnmapViewOfSection=(TNtUnmapViewOfSection)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"NtUnmapViewOfSection");用时HANDLE ProcessHandle=OpenProcess(...);HMODULE ImageBase=me32.hModule;
    NtUnmapViewOfSection(ProcessHandle,ImageBase);
      

  10.   

    如果是当前进程就直接NtUnmapViewOfSection((HANDLE)-1,ImageBase);
      

  11.   

    直接结束,以前看过。,我记得不是这样结束的。而是直接销毁这个模块!NtUnmapViewOfSection 不是API下的 nt.dll下的 必须使用LOADLIBARAR加载。
      

  12.   

    358  15E 0000DF0E NtUnmapViewOfSection
    这是Windows\system32\ntdll.dll中的一个函数,我刚用Dumpbin看了下,我试试。
      

  13.   

    你怎么知道我口吃。。麻烦些个这个代码处来我看看!你最好的方式是通过  CreateRemoteThread 远程注入方式来结束!
      

  14.   


    楼主的代码已经运行在目标进程,无须CreateRemoteThread 
      

  15.   

    谢谢两位,我应该已经胡结束模块,测试中那个进程崩溃了,可能是我中止我比较重要的模块。
    但是这人问题我还没有解决:3、如果中止成功了,怎样才能在快照中不显示?
    列宁同志说的 :“然后把PPEB_LDR_DATA Ldr;中的链表中的该模块项移除” 我还不知道实现方法。
    我现在能从PPEB中读取到进程的模块名、路径等信息,希望列宁同志再指导下。
    aaadddzxc
    也谢谢你
      

  16.   

    看这个
    typedef struct _PEB
    {
         UCHAR InheritedAddressSpace;
         UCHAR ReadImageFileExecOptions;
         UCHAR BeingDebugged;
         UCHAR BitField;
         /*ULONG ImageUsesLargePages: 1;
         ULONG IsProtectedProcess: 1;
         ULONG IsLegacyProcess: 1;
         ULONG IsImageDynamicallyRelocated: 1;
         ULONG SpareBits: 4;*/
         PVOID Mutant;
         PVOID ImageBaseAddress;
         PPEB_LDR_DATA Ldr;
         PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
         PVOID SubSystemData;
         PVOID ProcessHeap;
         PRTL_CRITICAL_SECTION FastPebLock;
         PVOID AtlThunkSListPtr;
         PVOID IFEOKey;
         ULONG CrossProcessFlags;
         ULONG ProcessInJob: 1;
         ULONG ProcessInitializing: 1;
         ULONG ReservedBits0: 30;
         union
         {
              PVOID KernelCallbackTable;
              PVOID UserSharedInfoPtr;
         };
         ULONG SystemReserved[1];
         ULONG SpareUlong;
     void* FreeList;
         ULONG TlsExpansionCounter;
         PVOID TlsBitmap;
         ULONG TlsBitmapBits[2];
         PVOID ReadOnlySharedMemoryBase;
         PVOID HotpatchInformation;
         VOID * * ReadOnlyStaticServerData;
         PVOID AnsiCodePageData;
         PVOID OemCodePageData;
         PVOID UnicodeCaseTableData;
         ULONG NumberOfProcessors;
         ULONG NtGlobalFlag;
         LARGE_INTEGER CriticalSectionTimeout;
         ULONG HeapSegmentReserve;
         ULONG HeapSegmentCommit;
         ULONG HeapDeCommitTotalFreeThreshold;
         ULONG HeapDeCommitFreeBlockThreshold;
         ULONG NumberOfHeaps;
         ULONG MaximumNumberOfHeaps;
         VOID * * ProcessHeaps;
         PVOID GdiSharedHandleTable;
         PVOID ProcessStarterHelper;
         ULONG GdiDCAttributeList;
         PRTL_CRITICAL_SECTION LoaderLock;
         ULONG OSMajorVersion;
         ULONG OSMinorVersion;
         WORD OSBuildNumber;
         WORD OSCSDVersion;
         ULONG OSPlatformId;
         ULONG ImageSubsystem;
         ULONG ImageSubsystemMajorVersion;
         ULONG ImageSubsystemMinorVersion;
         ULONG ImageProcessAffinityMask;
         ULONG GdiHandleBuffer[34];
         PVOID PostProcessInitRoutine;
         PVOID TlsExpansionBitmap;
         ULONG TlsExpansionBitmapBits[32];
         ULONG SessionId;
         ULARGE_INTEGER AppCompatFlags;
         ULARGE_INTEGER AppCompatFlagsUser;
         PVOID pShimData;
         PVOID AppCompatInfo;
         UNICODE_STRING CSDVersion;
         void * ActivationContextData;
         void * ProcessAssemblyStorageMap;
         void * SystemDefaultActivationContextData;
         void * SystemAssemblyStorageMap;
         ULONG MinimumStackCommit;
         void * FlsCallback;
         LIST_ENTRY FlsListHead;
         PVOID FlsBitmap;
         ULONG FlsBitmapBits[4];
         ULONG FlsHighIndex;
         PVOID WerRegistrationData;
         PVOID WerShipAssertPtr;
    } PEB, *PPEB;再看这个
    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;typedef struct _PEB_LDR_DATA
    {
         ULONG Length;
         UCHAR Initialized;
         PVOID SsHandle;
         LIST_ENTRY InLoadOrderModuleList;
         LIST_ENTRY InMemoryOrderModuleList;
         LIST_ENTRY InInitializationOrderModuleList;
         PVOID EntryInProgress;
    } PEB_LDR_DATA, *PPEB_LDR_DATA;这里有3个链表,InLoadOrderModuleList,InMemoryOrderModuleList,InInitializationOrderModuleList
    好像只有InLoadOrderModuleList才存在?你去试一下另外两个。
    使用这些链表可以枚举加载的dll
    找到相应的项后只要把那个从链表中移除即可使用NtReadVirtualMemory和NtWriteVirtualMemory来完成
      

  17.   

    CreateToolhelp32Snapshot通过创建远程线程来读取InLoadOrderModuleList枚举模块
      

  18.   

    如果你在当前进程操作就不需要NtReadVirtualMemory和NtWriteVirtualMemory
    直接操作内存即可
      

  19.   

    这些函数的使用说明我找不到,我的MSDN中没有,我再查下这些函数的用法。
    谢谢我不是对当前进程操作,简单讲是自己试着做个进程管理器玩,学习学习!
      

  20.   

    NtReadVirtualMemory,NtWriteVirtualMemory就是ReadProcessMemory,WriteProcessMemory用的东西
    你用ReadProcessMemory和WriteProcessMemory也行
      

  21.   

    那些链表的页受保护,如果用NtWriteVirtualMemory修改,首先用NtProtectVirtualMemory使页可写
    WriteProcessMemory会帮你完成这个操作
      

  22.   

    是的,我是在VS2005下用C++作Windwos窗体
      

  23.   

    啊,我刚开始学,很多还不懂,也不知道
    “为何不用win32api做界面”
    这是个什么软件?
      

  24.   

    CreateToolhelp32Snapshot就属于win32api
    我只是觉得用.net框架有点慢,占内存也多
      

  25.   

    你用visual c++创建的有图形用户界面的Win32 Project就是用的win32api
      

  26.   

    以前用过MFC,不喜欢就没有再用
      

  27.   

    WriteProcessMemory(hcid, pModule->BaseAddress , &tme, 1, &dwNumberOfBytesRead))
    ERROR_INVALID_ADDRESS
    487 Attempt to access invalid address. WriteProcessMemory(hcid, pModule->BaseAddress , &tme, 1, 0))也不行
      

  28.   

    typedef struct _LIST_ENTRY {
       struct _LIST_ENTRY *Flink;
       struct _LIST_ENTRY *Blink;
    } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
    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, LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    PLIST_ENTRY pListEntry;
    PLDR_MODULE pModule;
    pListEntry = pLdr->InMemoryOrderModuleList.Flink;
    pModule = (PLDR_MODULE)pListEntry ;
      

  29.   

    你怎么获取的pLdr,pModule 
    如果你操纵的是远程进程,peb->Ldr,pLdr->InMemoryOrderModuleList.Flink都是远程进程的地址
    需要使用NtReadVirtualMemory读取,不能直接->
      

  30.   

    int main(int argc, char* argv[])  
    {   BOOL EnableDebugPrivilege() ; 
    PPEB pPEB;
    char str[200];
    //HWND hLog;
    PPEB_LDR_DATA pLdr;
    PLIST_ENTRY pListEntry;
    PLDR_MODULE pModule;
    char DllName[300];
    RMTDATA stRmtData   = {0}; 
    _asm{
    push eax
    mov eax,fs:[30h]
    mov pPEB, eax
    pop eax
    }
    pLdr = pPEB->LoaderData; pListEntry = pLdr->InLoadOrderModuleList.Flink; HANDLE hcid; if (pLdr->InMemoryOrderModuleList.Flink)
    {
    pListEntry = pLdr->InMemoryOrderModuleList.Flink; while(pListEntry != &pLdr->InMemoryOrderModuleList)
    {
    pModule = (PLDR_MODULE)/*(*/pListEntry /*- 1)*/; WideCharToMultiByte(CP_ACP, 0, pModule->FullDllName.Buffer, pModule->FullDllName.Length, DllName, 300, NULL, FALSE); printf("模块名 :%s\n", DllName); sprintf(str, "BaseAddress: 0x%08X sizeofImage: 0x%08X", pModule->BaseAddress, pModule->SizeOfImage); printf("地址 :%s\n", str); if(strcmp(DllName, "msvcrt.dll") == 0)
    {
    hcid = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_WRITE | PROCESS_VM_OPERATION, TRUE, GetCurrentProcessId());
    if(hcid != NULL){ int tme = 97;
    DWORD dwNumberOfBytesRead; if(!WriteProcessMemory(hcid, pModule->BaseAddress , &tme, 1, &dwNumberOfBytesRead))
    {
    printf("%d\n", GetLastError());
    //system("pause");
    }
    if(!WriteProcessMemory(hcid, pModule->BaseAddress , "5", 1, 0))
    {
    printf("%d\n", GetLastError());
    //system("pause");
    }
    }
      
      ::CloseHandle(hcid);
    } pListEntry = pListEntry->Flink;
    } } pListEntry = pLdr->InLoadOrderModuleList.Flink;
    printf("%s\n\n", "--");
    printf("************************** :%s\n", "***");
    printf("%s\n\n", "--"); if (pLdr->InMemoryOrderModuleList.Flink)
    {
    pListEntry = pLdr->InMemoryOrderModuleList.Flink; while(pListEntry != &pLdr->InMemoryOrderModuleList)
    {
    pModule = (PLDR_MODULE)/*(*/pListEntry /*- 1)*/; WideCharToMultiByte(CP_ACP, 0, pModule->FullDllName.Buffer, pModule->FullDllName.Length, DllName, 300, NULL, FALSE); printf("模块名 :%s\n", DllName); sprintf(str, "BaseAddress: 0x%08X sizeofImage: 0x%08X", pModule->BaseAddress, pModule->SizeOfImage); printf("地址 :%s\n", str);
    pListEntry = pListEntry->Flink;
    } }
    system("pause");  
    return 0;  
    }  
      

  31.   

    pModule = (PLDR_MODULE)(pListEntry - 1);
    这里要减1
      

  32.   

    pModule = (PLDR_MODULE)(pListEntry - 1);
    这样改回来后程序是不报错了,但第二次遍历取得的数据中,“msvcrt.dll”这个模块仍然存在,其他模块也没有改变。
      

  33.   

    列宁同志,先结贴了,问题还没有解决。
    现在WriteProcessMemory能完成写入,但读取的数据仍然没有更改。
    另开一新贴再探讨内存写入的问题。
    新贴位置:
    http://topic.csdn.net/u/20110228/10/7c003de4-d410-4aae-9e08-afbc14fcbeb6.html