这是我用来中止一个进程的模块的代码。
问题是:
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、这样中止进程的模块是否正确?
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;
}}
while(...)
{
StopModule();
}
我查下用法
先通过模块基地址找到dllmain地址,再使用DLL_PROCESS_DETACH调用dllmain
然后把PPEB_LDR_DATA Ldr;中的链表中的该模块项移除
最后用NtUnmapViewOfSection撤销模块section的映射
能不能给我个示例?
我用的的VS2005,没有NtUnmapViewOfSection这个东东。
谢谢。
或者
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);
这是Windows\system32\ntdll.dll中的一个函数,我刚用Dumpbin看了下,我试试。
楼主的代码已经运行在目标进程,无须CreateRemoteThread
但是这人问题我还没有解决:3、如果中止成功了,怎样才能在快照中不显示?
列宁同志说的 :“然后把PPEB_LDR_DATA Ldr;中的链表中的该模块项移除” 我还不知道实现方法。
我现在能从PPEB中读取到进程的模块名、路径等信息,希望列宁同志再指导下。
aaadddzxc
也谢谢你
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来完成
直接操作内存即可
谢谢我不是对当前进程操作,简单讲是自己试着做个进程管理器玩,学习学习!
你用ReadProcessMemory和WriteProcessMemory也行
WriteProcessMemory会帮你完成这个操作
“为何不用win32api做界面”
这是个什么软件?
我只是觉得用.net框架有点慢,占内存也多
ERROR_INVALID_ADDRESS
487 Attempt to access invalid address. WriteProcessMemory(hcid, pModule->BaseAddress , &tme, 1, 0))也不行
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 ;
如果你操纵的是远程进程,peb->Ldr,pLdr->InMemoryOrderModuleList.Flink都是远程进程的地址
需要使用NtReadVirtualMemory读取,不能直接->
{ 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;
}
这里要减1
这样改回来后程序是不报错了,但第二次遍历取得的数据中,“msvcrt.dll”这个模块仍然存在,其他模块也没有改变。
现在WriteProcessMemory能完成写入,但读取的数据仍然没有更改。
另开一新贴再探讨内存写入的问题。
新贴位置:
http://topic.csdn.net/u/20110228/10/7c003de4-d410-4aae-9e08-afbc14fcbeb6.html