P>На любое не получится, если память общая для всех потоков.
Вот, оптимизированный вариант. Быстро обнуляет все DWORDы в указанном процессе. Масштабируется на любое количество процессоров.
#include <windows.h>
#include <queue>
#include <vector>
#include <algorithm>
class AbsoluteZero
{
HANDLE _process;
typedef std::queue<MEMORY_BASIC_INFORMATION> MemoryRanges;
typedef std::vector<HANDLE> Handles;
MemoryRanges _mem_ranges;
CRITICAL_SECTION _cs;
void ZeroThatDwords(PDWORD ptr, SIZE_T count)
{
for(;count;--count,++ptr)
{
DWORD etalon = 0, written;
::WriteProcessMemory(_process, ptr, &etalon, sizeof(etalon), &written);
}
}
void ThreadRoutine()
{
for(;;)
{
MEMORY_BASIC_INFORMATION mbi;
::EnterCriticalSection(&_cs);
bool exit = _mem_ranges.empty();
if (!exit)
{
mbi = _mem_ranges.front();
_mem_ranges.pop();
}
::LeaveCriticalSection(&_cs);
if (exit) break;
ZeroThatDwords((PDWORD)mbi.BaseAddress, mbi.RegionSize/sizeof(DWORD));
}
}
static DWORD CALLBACK StaticThreadRoutine(void *p)
{
((AbsoluteZero*)p)->ThreadRoutine();
return 0;
}
void QueryMemory()
{
for(PCHAR ptr = NULL;ptr<(PCHAR)MAXLONG_PTR;)
{
MEMORY_BASIC_INFORMATION mbi = {0};
if (::VirtualQueryEx(_process, ptr, &mbi, sizeof(mbi)) && ((PCHAR)mbi.BaseAddress+mbi.RegionSize)>ptr)
{
if ( mbi.State!=MEM_FREE && mbi.State!=MEM_RESERVE &&
(mbi.Protect==PAGE_READWRITE || mbi.Protect==PAGE_WRITECOPY ||
mbi.Protect==PAGE_EXECUTE_READWRITE || mbi.Protect==PAGE_EXECUTE_WRITECOPY))
{
_mem_ranges.push(mbi);
}
ptr = (PCHAR)mbi.BaseAddress + mbi.RegionSize;
}
else
ptr+= 0x1000;
}
}
void InitializeThreads(Handles &threads)
{
DWORD_PTR max_affinity = 0x01, sys_affinity;
if (!::GetProcessAffinityMask(::GetCurrentProcess(), &max_affinity, &sys_affinity))
max_affinity = 0x01;
for(DWORD_PTR i = 1; i; i<<=1)
{
if (max_affinity&i)
{
DWORD tid;
HANDLE trd = ::CreateThread(NULL, 0, StaticThreadRoutine, this, CREATE_SUSPENDED, &tid);
if (trd)
{
::SetThreadAffinityMask(trd, i);
::ResumeThread(trd);
threads.push_back(trd);
}
}
}
}
public:
AbsoluteZero(DWORD pid) throw (std::runtime_error)
{
_process = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, pid);
if (!_process)
{
throw std::runtime_error("failed to capture process handle");
}
::InitializeCriticalSection(&_cs);
}
virtual ~AbsoluteZero()
{
::DeleteCriticalSection(&_cs);
::CloseHandle(_process);
}
void ZeroAllDwords()
{
QueryMemory();
printf("%u memory regions found\n", _mem_ranges.size());
Handles threads;
InitializeThreads(threads);
if (threads.empty())
{
printf("Low resources condition - cannot create threads\n");
ThreadRoutine();
}
else
{
printf("%u thread started\n", threads.size());
for(size_t i=0; i<threads.size(); i+=MAXIMUM_WAIT_OBJECTS)
{
::WaitForMultipleObjects(min(threads.size()-i, MAXIMUM_WAIT_OBJECTS), &threads[i], TRUE, INFINITE);
}
std::for_each(threads.begin(), threads.end(), ::CloseHandle);
}
}
};
int main(int argc, const char *argv[])
{
try
{
if (argc!=2)
throw std::runtime_error("You should specify one additional parameter - process wich DWORDs must be zeroed\n");
DWORD ticks = ::GetTickCount();
AbsoluteZero(atoi(argv[1])).ZeroAllDwords();
printf("Zeroing complete in %u msec\n", ::GetTickCount()-ticks);
}
catch(std::runtime_error &e)
{
printf("Error: %s [%u]\n", e.what(), ::GetLastError());
}
return 0;
}