[MSDN][列举][进程]MSDN中列举进程代码无法运行出结果问题

09月 18th, 2008 by admin
Posted in VC/MFC | No Comments »

我复制了MSDN中列举所有进程的代码,但执行后无法打印出结果,
不知道是怎么回事:
BOOL GetProcessW1::GetProcessList(){
HANDLE        hProcessSnap = NULL;
    BOOL          bRet      = FALSE;
    PROCESSENTRY32 pe32      = {0};

    //  Take a snapshot of all processes in the system.

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    //  Fill in the size of the structure before using it.

    pe32.dwSize = sizeof(PROCESSENTRY32);

    //  Walk the snapshot of the processes, and for each process,
    //  display information.

    if (Process32First(hProcessSnap, &pe32))
    {
        DWORD        dwPriorityClass;
        BOOL          bGotModule = FALSE;
        MODULEENTRY32 me32      = {0};

        do
        {
            bGotModule = GetProcessModule(pe32.th32ProcessID,
                pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32));

            if (bGotModule)
            {
                HANDLE hProcess;

                // Get the actual priority class.
                hProcess = OpenProcess (PROCESS_ALL_ACCESS,
                    FALSE, pe32.th32ProcessID);
                dwPriorityClass = GetPriorityClass (hProcess);
                CloseHandle (hProcess);

                // Print the process's information.
                printf( "
Priority Class Base %d
",
                    pe32.pcPriClassBase);
                printf( "PID %d
", pe32.th32ProcessID);
                printf( "Thread Count %d
", pe32.cntThreads);
                printf( "Module Name %s
", me32.szModule);
                printf( "Full Path %s

", me32.szExePath);

//
CString str,strTemp=" ";
str.Format("%d",pe32.pcPriClassBase);
strTemp+=str;
strTemp+="  ;  ";

str.Format("%d",pe32.th32ProcessID);
strTemp+=str;
strTemp+="  ;  ";

str.Format("%d",pe32.cntThreads);
strTemp+=str;
strTemp+="  ;  ";

str.Format("%s",me32.szModule);
strTemp+=str;
strTemp+="  ;  ";

str.Format("%s",me32.szExePath);
strTemp+=str;
strTemp+="  ;  ";

pMainView->m_ProcessList.AddString(strTemp);

pMainView->UpdateData(FALSE);

            }
        }
        while (Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;    // could not walk the list of processes

    // Do not forget to clean up the snapshot object.

    CloseHandle (hProcessSnap);
    return (bRet);

}

BOOL GetProcessModule (DWORD dwPID, DWORD dwModuleID,
    LPMODULEENTRY32 lpMe32, DWORD cbMe32)
{
    BOOL          bRet        = FALSE;
    BOOL          bFound      = FALSE;
    HANDLE        hModuleSnap = NULL;
    MODULEENTRY32 me32        = {0};

    // Take a snapshot of all modules in the specified process.

    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    if (hModuleSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    // Fill the size of the structure before using it.

    me32.dwSize = sizeof(MODULEENTRY32);

    // Walk the module list of the process, and find the module of
    // interest. Then copy the information to the buffer pointed
    // to by lpMe32 so that it can be returned to the caller.

    if (Module32First(hModuleSnap, &me32))
    {
        do
        {
            if (me32.th32ModuleID == dwModuleID)
            {
                CopyMemory (lpMe32, &me32, cbMe32);
                bFound = TRUE;
            }
        }
        while (!bFound && Module32Next(hModuleSnap, &me32));

        bRet = bFound;  // if this sets bRet to FALSE, dwModuleID
                        // no longer exists in specified process
    }
    else
        bRet = FALSE;          // could not walk module list

    // Do not forget to clean up the snapshot object.

    CloseHandle (hModuleSnap);

    return (bRet);
}

编译之后有没有出错啊??
代码怎么可以全部复制呢??  你得修改下 适合自己的工程啊  你看看里面的 CString  需要的是 mfc支持的    printf  是控制台的 你建立工程的时候 选择对了没有??必须的头文件包含了没有??

引用 2 楼 rollrock1987 的回复:
编译之后有没有出错啊??
代码怎么可以全部复制呢??⠠你得修改下 适合自己的工程啊⠦nbsp; 你看看里面的 CString⠠需要的是 mfc支持的⠠⠠printf⠠是控制台的 你建立工程的时候 选择对了没有??必须的头文件包含了没有??

编译是没有问题的,问题也不是出在这里。问题是程序根本没有进入到打印那段语句块里面,也就是说
if (bGotModule) 中的bGotModule始终是为FALSE的,含CString那一段是我自己加入的

me32.dwSize = sizeof(MODULEENTRY32);

引用 4 楼 jacklzw88 的回复:
me32.dwSize = sizeof(MODULEENTRY32);

??,程序中有这一句呀

单步调试下,看到什么地方运行不下去了?

引用 6 楼 yjgx007 的回复:
单步调试下,看到什么地方运行不下去了?

运行得下去,就是运行GetProcessModule返回FALSE,不知道怎么回事,帮忙调试一下,谢谢

经过试验得出,如果不判断dwModuleID,则可以得到信息,在我的机器上me32.th32ModuleID 一直为1,而传入的dwModuleID为0
//  do
        {
          // if (me32.th32ModuleID == dwModuleID)
            {
                CopyMemory (lpMe32, &me32, cbMe32);
                bFound = TRUE;
            }
        }
      // while (!bFound && Module32Next(hModuleSnap, &me32));

//以前写的,模拟任务管理器的
HANDLE snapshot;
snapshot=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 processliststr[50];
for(int j=0;j <50;j++)
processliststr[j].dwSize=sizeof(PROCESSENTRY32);
BOOL return_value;
int i=0;
        int m;
return_value=::Process32First(snapshot,&processliststr[i]);
m_showlist.DeleteAllItems();

CString str;

while(return_value)
{
      m=m_showlist.InsertItem(i,(LPTSTR)processliststr[i].szExeFile);
 
  str.Format("%d",processliststr[i].cntThreads);
  m_showlist.SetItemText(m,1,str);
       
  str.Format("%d",processliststr[i].th32ProcessID); 
  m_showlist.SetItemText(m,2,str);
     
  str.Format("%d",processliststr[i].pcPriClassBase);
  m_showlist.SetItemText(m,3,str);
         

  m_ProcessIndex[i]=processliststr[i].th32ProcessID;
  i++;
  return_value=::Process32Next(snapshot,&processliststr[i]);  
   
}

引用 7 楼 RedskyDeng 的回复:
引用 6 楼 yjgx007 的回复:
单步调试下,看到什么地方运行不下去了?

运行得下去,就是运行GetProcessModule返回FALSE,不知道怎么回事,帮忙调试一下,谢谢


你自已调试下,在GetProcessModule里面step into, 看到哪里不执行返回FALSE?

引用 8 楼 cwc270 的回复:
经过试验得出,如果不判断dwModuleID,则可以得到信息,在我的机器上me32.th32ModuleID 一直为1,而传入的dwModuleID为0
//⠠do
{
// if (me32.th32ModuleID == dwModuleID)
{
CopyMemory (lpMe32, &me32, cbMe32);
bFound = TRUE;
}
}
// while (!bFound && Module32Next(hModuleSnap, &me32));

的确,请问是怎么回事,我把这个判断去掉就OK了,MSDN中的这个判断是什么意思?

me32.dwSize = sizeof(MODULEENTRY32);

你自己再仔细看看。

引用 12 楼 jacklzw88 的回复:
me32.dwSize = sizeof(MODULEENTRY32);

你自己再仔细看看。


没搞懂,请指点

th32ModuleID
Module identifier of the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by functions other than the ToolHelp functions.

th32ModuleID
Module identifier in the context of the owning process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by functions other than the ToolHelp functions.

看下这两段英文就明白了…仅仅是对函数调用产生影响,用于模块比较是错误的…

引用 14 楼 gavin1203 的回复:
th32ModuleID
Module identifier of the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by functions other than the ToolHelp functions.

th32ModuleID
Module identifier in the context of the owning process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by func…


是呀,你的这个英文文档哪里面的,我的代码可是在MSDN中的,不是我自己写的,我搞不大明白了

调整权集,将运行级上调到最高

Tags: , , ,

[强制][结束][进程]如何强制结束一个进程

09月 17th, 2008 by admin
Posted in VC/MFC | No Comments »

在多线程调试的时候(XP操作系统下),经常会出现死机的现象,不得不进行重启才能解决。
后来找到一个名为antifreeze的国外软件,在几乎死机的时候还可以调用该程序,将环境进程结束掉。
另外发现,VC环境下,在设置断点断下的时候,这个时候即使用任务管理器无法将此刻调试的进程结束掉,这是为什么?

我的问题是,在系统几乎死机的时候,如果让自己的程序还能获取CPU分配的时间,将我需要结束的进程结束掉?谢谢

普通方法都试了,不行,因为多线程死机的时候,几乎没有程序可以响应了。

有些时候是死在内核模式下,这时候进程管理器通常无法结束。或许有些情况可以利用驱动程序在内核模式下结束进程。

引用 1 楼 jameshooo 的回复:
一个偏方:在你的程序中启动一个console窗口,然后执行调试去,如果出现任何问题,console窗口还是能响应的,直接关闭console窗口就能退出你的进程

能具体给出实例吗?谢谢!

LS的方法不错,学习了!

引用 1 楼 jameshooo 的回复:
一个偏方:在你的程序中启动一个console窗口,然后执行调试去,如果出现任何问题,console窗口还是能响应的,直接关闭console窗口就能退出你的进程

mark

AllocConsole/FreeConsole即可

多线程调试的时候,确实是会经常假死,但是可以用以下方法解决(本人经验。^^)
打开记事本,写一些东西,别保存,当调试发生假死的时候。可以按ctrl+alt+del选择注销,系统会把VC给结束掉,之后会问时候保存文件,点取消即可恢复正常。从而避免重新启动机器。

以前编译过一个GINA(代码不是我的)。就是对付VC调试造成系统假死的。同样有效。

———————
我的问题是,在系统几乎死机的时候,如果让自己的程序还能获取CPU分配的时间,将我需要结束的进程结束掉?谢谢

普通方法都试了,不行,因为多线程死机的时候,几乎没有程序可以响应了。
———————-
你说的这些话是不对的,首先假死的时候,系统还可以快速响应热键!例如ctrl+alt+del,antifreeze也是如此。其次,发生假死的时候CPU空闲接近100%!不信你就按下热键,选择任务管理器。第三,antifreeze接收到热键,会切换到另外一个桌面,并挂起所有的线程,结束进程应该是TerminateProcess,我在调试器里发现它被调用。第四,要结束的进程不是被调试进程,而是VC。

关注 接分

Tags: , , ,

[进程][注入][钩子]XP哪些进程不能注入DLL挂钩子

09月 14th, 2008 by admin
Posted in VC/MFC | No Comments »

很奇怪,我的一个全局钩子自己运行完全没有问题,
我和同学用完全相同的XP盘状的两个虚拟机,
我的机器上运行完全没有问题,他的注入后说什么services.exe出错,
郁闷,我现在都怀疑是不是挂钩和硬件有关了。

以前他的是注入winlogon后蓝屏,我的没有问题,所以后来我就不注winlogon了

请教高手,这是什么原因引起的

或者挂钩有哪些要注意的??

全局钩子有什么好的啊…最底层的东西又钩不到…而且全局钩子很容易出事情.

引用 1 楼 cnzdgs 的回复:
与你的代码有关,你试试什么都不做应该就没问题了。

不知道全局钩子对操作有什么限制,
比如说不能发送进程间的消息等等?
我就是钩到我要的API 后用sendmessage返回主模块一个消息,
而且在我的机器上运行完全没有问题

引用 2 楼 lvshaoqing 的回复:
全局钩子有什么好的啊…最底层的东西又钩不到…而且全局钩子很容易出事情.

那你有什么更好的方法吗?

SendMessage可能存在两种问题:
1、SendMessage向其它线程的窗口发消息时,要等待窗口处理完该消息后才返回,有些时候程序是不能等待的,所以可能会引发问题;
2、每个进程都有自己独立的地址空间,进程间不能利用指针来传递数据,否则很容易产生异常。

根据你的问题描述来看,应该是Hook的代码本身出了问题,你把代码贴出来看看。

引用 5 楼 cnzdgs 的回复:
SendMessage可能存在两种问题:
1、SendMessage向其它线程的窗口发消息时,要等待窗口处理完该消息后才返回,有些时候程序是不能等待的,所以可能会引发问题;
2、每个进程都有自己独立的地址空间,进程间不能利用指针来传递数据,否则很容易产生异常。

根据你的问题描述来看,应该是Hook的代码本身出了问题,你把代码贴出来看看。

首先感谢!
注入DLL我用的是Windows 程序设计(王艳平)编写的类:class CRemThreadInjector。开始时枚举所有进程,远程注入,

HOOKAPI用得Jeffrey的CAPIHook类 ,都没有做修改。
HOOKAPI很多贴一两个吧:

extern CAPIHook g_WriteFile;

CAPIHook g_WriteFile("kernel32.dll", "WriteFile", (PROC)Hook_WriteFile);

HANDLE WINAPI Hook_WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
typedef HANDLE (WINAPI *PFNTERMINATEPROCESS)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);

// 取得主模块的文件名称
char szPathName[MAX_PATH];

::GetModuleFileName(NULL, szPathName, MAX_PATH);

/////////////////////////////////////////////////////////
NTSTATUS status = -1;
    HMODULE hNtdll = NULL;
IO_STATUS_BLOCK IoStatus = {0};
wchar_t FileInfo[MAX_PATH+2];
LPSTR p;
char szFilePath[MAX_PATH];
 
RtlZeroMemory(szFilePath, MAX_PATH);
hNtdll = LoadLibrary(_T("ntdll.dll"));
if(hNtdll!=NULL)
{
NtQueryInformationFile = (NTQUERYINFORMATIONFILE)GetProcAddress(hNtdll, "NtQueryInformationFile");

if(NtQueryInformationFile!=NULL)
{
if (hFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory((void*)&FileInfo, MAX_PATH);
status = NtQueryInformationFile(hFile, &IoStatus, (PVOID)FileInfo, MAX_PATH+2, FileNameInformation);
if (NT_SUCCESS(status))
{
wchar_t* temp=&FileInfo[0];
temp=temp+2;
char* AnsiPath=UnicodeToAnsi((LPCTSTR)temp);
GetFullPathNameA(AnsiPath, MAX_PATH, szFilePath, &p);
}
}
}
}

    FreeLibrary(hNtdll);
////////////////////////////////////////////////////////////////
// 构建发送给主窗口的字符串
char sz[2048];
wsprintf(sz, "%d
%s
WriteFile
%s
", ::GetCurrentProcessId(), szPathName, szFilePath);

// 发送这个字符串到主对话框
COPYDATASTRUCT cds = { ::GetCurrentProcessId(), strlen(sz) + 1, sz };
::SendMessageTimeout(::FindWindow(NULL, "HookComu"), WM_COPYDATA, 0, (LPARAM)&cds, SMTO_ABORTIFHUNG, 10, NULL);

return ((PFNTERMINATEPROCESS)(PROC)g_WriteFile)(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);

}

此外还HOOK了很多注册表的操作,大约HOOk了28个API

引用 5 楼 cnzdgs 的回复:
SendMessage可能存在两种问题:
1、SendMessage向其它线程的窗口发消息时,要等待窗口处理完该消息后才返回,有些时候程序是不能等待的,所以可能会引发问题;
2、每个进程都有自己独立的地址空间,进程间不能利用指针来传递数据,否则很容易产生异常。

根据你的问题描述来看,应该是Hook的代码本身出了问题,你把代码贴出来看看。

除了SendMessage,有其他不使用指针传递消息的方法吗?

我现在只会用也只知道SendMessage这一个?

我刚才试了下,卡吧和瑞心的进程,哈哈完全不行….

Tags: , , ,

[判断][winword.exe][进程]!!!!如何判断winword.exe进程是office中的word

09月 13th, 2008 by admin
Posted in VC/MFC | No Comments »

如何知道word进程不是其他进程改名字冒充的呢?

进行md5或者sha1之类的字串对比,也是现在的常用方法

进程数字签名,MD5

请问你说的md5是对winword.exe进行md5么?
要是这样的话不同的版本之间是不是需要都取md5呢?

对,没错

up up
study study

使用版本查询函数应该可以。

Tags: , , ,

[GetMessage][消息][进程]GetMessage是不是在没有消息的情况下进程(线程)处于阻塞状态

08月 22nd, 2008 by admin
Posted in VC/MFC | No Comments »

在WinMain函数中的消息循环中:
wile(GetMessage(&msg, NULL, 0, 0)) {…}
这里有两个问题:
1、WinMain中的GetMessage是从操作系统中的消息队列来获取消息的。那么如果这个消息循环是在某个子线程中的,那么GetMessage又是从什么地方来获取消息的呢?
  注:我知道可以通过PostThreadMessage(ThreadId, WM_㗃𗃗, NULL, NULL)来往线程中发消息,但是我相知道的是这个消息是发到操作系统的消息队列吗?

2、如题,因为这里的消息循环在得到WM_QUIT前是个死循环,如果GetMessage在没有消息时也一直运行,那么是不是很耗资源吗?所以我认为在没有资源时应该处于阻塞状态。

3、哪位兄弟手上有详细的消息对象的数据结构不妨拿出来共享一下^_^,俺手上的这本书不巧没有消息的数据结构的详细介绍。

1、每个线程都有自己的消息队列。GetMessage是从当前线程的消息队列中取消息。PostThreadMessage是发送到线程的消息队列中。

2、你的猜想是正确的。消息队列中没有消息GetMessage是不会返回的。和GetMessage不同,PeekMessage是不阻塞,立即返回。

3、《Windows核心编程》书中有详细介绍,这本书有电子版的。

2,WM_QUIT是请求应用程序退出的消息,对系统来讲,它与其他消息没有什么不同。你提的阻塞,感觉很可怕。不太明确你说的阻塞是什么意思。个人认为,你使用这个词是错误的。

各种消息(包括用户定义的消息)在系统内排队,每个程序只是负责消费它,就是说,我用的时候,我就Get,不用它,就不Get。。。。

哪来的阻塞?

3,看MSDN,这是最好的书。

对你得问题:
1、GetMessage从当前线程消息队列,而不是所谓得操作系统队列获得
2、没有资源时处于阻塞状态,不需要消耗资源。这里3楼得理解可能有点问题

3、不建议看其所谓得消息结构,对你毫无意义,看windows核心编程也许不错

无论哪本介绍MFC的书籍,都有说到过这个问题,GetMessage函数在没有消息时的确是阻塞的,不消耗CPU,这是书上明确说明的。
你可以用SDK的方式写个程序测试一下,不难,网上很多

各种消息(包括用户定义的消息)在系统内排队,每个程序只是负责消费它,就是说,我用的时候,我就Get,不用它,就不Get。。。。

哪来的阻塞?
=======================
这样说不对,用的时候就Get,不用时就不Get,这根本不可能,GetMessage在没有消息时是阻塞的,也就是不返回,线程停在GetMessage处,另一个PeekMessage和它不同,它是没有消息时也返回,以前有人利用这个函数在程序空闲时作一些工作。

各种消息(包括用户定义的消息)在系统内排队,每个程序只是负责消费它,就是说,我用的时候,我就Get,不用它,就不Get。。。。

哪来的阻塞?
=======================
这样说不对,用的时候就Get,不用时就不Get,这根本不可能,GetMessage在没有消息时是阻塞的,也就是不返回,线程停在GetMessage处,另一个PeekMessage和它不同,它是没有消息时也返回,以前有人利用这个函数在程序空闲时作一些工作。

是的

我看到的所有的情况,都是循环GetMessage的,“不用时不get”,怎么实现呢?消息循环对线程至关重要,所有基于消息的线程都有义务随时monitor消息,不能等到特定时候再get(怎么等待呢?)

学习一下!

GET、PEEK、SEND、POST消息很好理解

GET就是不GET到不罢休
PEEK只是看看有没有消息,有就拿,没有就走人
SEND是要一直等到对方收到了才放心
POST只是把消息放在邮筒里就不管走人了

消息循环的语句如下:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
其中,GetMessage如果收到非WM_QUIT的消息,会返回非0值;如果收到WM_QUIT消息,会返回0值。另外,GetMessage在没有消息时是阻塞的,也就是不返回,线程被操作系统挂起。

Tags: , , ,

[windows][系统][进程]windows系统中如何使进程启动的大量线程(几百个)以相同的优先级同时执行

08月 5th, 2008 by admin
Posted in VC/MFC | No Comments »

windows系统(2k,xp,2k3)中如何使进程启动的大量线程(几百个)以相同的优先级同时执行?

我的程序是基于MFC的,以相同参数启动大量线程,各个线程都做同样的事情,所以希望这些线程获得均等的执行机会,可是实际运行起来却发现并没有达到期望的效果,有少数线程执行频率较高,更多的线程却“躺在那里睡大觉”,相差悬殊。即便是当运行几十个线程时也是这种现象。请了解内情的朋友指点迷津。

一般时间片轮询的调度方式可以在相同的优先级下有相同的执行机会,
抢占式调度方式下同优先级的任务在任务栈前的优先获得执行机会,系统处理速度足够快或是线程中Sleep的时间足够长才能达到基本均等的机会

引用 2 楼 zgl7903 的回复:
一般时间片轮询的调度方式可以在相同的优先级下有相同的执行机会,
抢占式调度方式下同优先级的任务在任务栈前的优先获得执行机会,系统处理速度足够快或是线程中Sleep的时间足够长才能达到基本均等的机会

对!
windows抢占式的很难保证都一起运行!

大量线程~~~我晕

活跃的(非阻塞的)线程数目等于CPU核数目时,是效率最佳的。
线程数目过多造成系统资源浪费,以及线程切换开销,效率反而会随着线程数目增多而下降。
因此尽量不要开启大量的线程。

默认启动的线程,优先级是相同的。只是具体的调度机会,由Windows的调度算法来决定,而这调度算法又是不公开的,所以不知道如何才能公平。

在绝大多数情况下,起最大数量的线程都不是好注意。线程过多,不但不会有太多的性能提高,反而可能降低效率。

注意:线程提高性能只在各个线程有互不相关的不需要CPU的任务时才有大的提高,如果所有的线程都忙,则比CPU个数多很多倍个数的线程往往都会极大降低效率

你是如何启动线程的?在线程中做了哪些事?如何得出结论的?
可以这样测试一下:线程启动后都等待同一个手动复位的事件,该事件由主线程在创建完所有线程后触发,线程中执行一个循环,检查一个标志变量作为循环结束条件,循环中将一个记数变量每次加1,该变量由主线程初始化为0,在创建线程时通过参数传递指针过来,当执行足够长的一段时间后,右主线程设置标志变量停止所有线程,然后检查各个记数变量的值。

引用楼主 BlueEngine 的帖子:
windows系统(2k,xp,2k3)中如何使进程启动的大量线程(几百个)以相同的优先级同时执行?

我的程序是基于MFC的,以相同参数启动大量线程,各个线程都做同样的事情,所以希望这些线程获得均等的执行机会,可是实际运行起来却发现并没有达到期望的效果,有少数线程执行频率较高,更多的线程却“躺在那里睡大觉”,相差悬殊。即便是当运行几十个线程时也是这种现象。请了解内情的朋友指点迷津。

你的某些线程可能由于资源申请未满足,而没有在CPU队列中排上号。

是要搞 几百个CPU吗?

感谢大家的回复。
我的程序是用来管理设备的,线程用来轮询设备状态信息。线程的工作就是发送查询请求以及对得到的结果进行分析,循环往复。各个线程之间没有同步操作,各自独立。
根据以上朋友们的提示,这个模型确实有问题。大家有否合理的解决办法?

cnzdgs: 我得出结论的方式与你提供的思路大体一致。只不过我是直接用TRACE把那个变量输出了,我在调试模式下观察的结果。

得到的结果大概是什么样的规律?如果线程不是同时开始工作,则可能先创建的线程执行时间多一些;如果线程不是同时停止工具,则可能后结束的线程执行时间多一些。

对,大体上是这样,但也有出入。
假如不考虑调整程序结构,有否思路可以改善这个结果?

不是线程越多越好,根据CPU的数量而定。
除了系统线程,最好开辟CPU数量 * 2个线程,否则线程直接切换消耗大量的CPU时间

明白线程不是越多越好。只是没想到会是这么一种情况。我的应用是常规应用,在普通PC上运行,不是多路CPU的系统。考虑改进程序结构中,仍然希望得到大家的指点。

深入学习啊

这样的情况不建议使用多线程

系统要为进程、线程所需的上下文信息使用内存。因此,可以创建的进程、AppDomain 对象和线程的数目会受到可用内存的限制。
跟踪大量的线程将占用大量的处理器时间。如果线程过多,则其中大多数线程都不会产生明显的进度。如果大多数当前线程处于一个进程中,则其他进程中的线程的调度频率就会很低。
如过你是在处理输入输出相关的应用程序,可以试一试完成端口(IOCP);

感谢各位,对多线程的使用又多了些了解。暂使用threadpool解决,能有效缓解当前这种状况。

线程启动后把ID记下来, 想用哪个用哪个

Tags: , , ,

[进程]关于进程列表的问题

08月 1st, 2008 by admin
Posted in VC/MFC | No Comments »

写一个函数实现把本机所有进程信息放进一个列表

BOOL CFireWallApp::GetProcessList(CListCtrl &mylist)
{
HANDLE  SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
if(SnapShot==NULL) 
{   
return  FALSE; 

SHFILEINFO  shSmall; 
int  nIndex; 
CString  str,prcnum; 
PROCESSENTRY32  ProcessInfo;//声明进程信息变量 
ProcessInfo.dwSize=sizeof(ProcessInfo);//设置ProcessInfo的大小 
//返回系统中第一个进程的信息 
BOOL  Status=Process32First(SnapShot,&ProcessInfo); 
int  m_nProcess=0,num=0; 
while(Status) 

m_nProcess++; 
num++; 
//获取进程文件信息 
SHGetFileInfo(ProcessInfo.szExeFile,0,&shSmall, 
            sizeof(shSmall),SHGFI_ICON &brvbarSHGFI_SMALLICON); 
//在列表控件中添加映像名称 
mylist.InsertItem(m_nProcess-1,"");
mylist.SetItemText(m_nProcess-1,2,ProcessInfo.szExeFile)
//获取下一个进程的信息 
Status=Process32Next(SnapShot,&ProcessInfo); 
}
return TRUE;
}

但是在编译的时候error C2065:CreateToolhelp32Snapshot' : undeclared identifier
              error C2065: 'TH32CS_SNAPPROCESS' : undeclared identifier

我已经在文件头部添加
#include <windows.h>
#include "tlhelp32.h"
#include <stdio.h>

为什么会识别不了呢

还有个问题,请问如何把进程的图标也放进列表中呢????

CreateToolhelp32Snapshot这种快照方式不好的哦...已经有方法隐藏了...

ExtractIcon

你也可以直接读取pe文件的res数据段

还没有帮我解决为什么会

error C2065:CreateToolhelp32Snapshot' : undeclared identifier
error C2065: 'TH32CS_SNAPPROCESS' : undeclared identifier

引用 5 楼 nandizhu 的回复:
还没有帮我解决为什么会

error C2065:CreateToolhelp32Snapshot' : undeclared identifier
error C2065: 'TH32CS_SNAPPROCESS' : undeclared identifier

有没有加头文件哦....windows.h

肯定加了的啊

Tags: ,

[hook][进程][WM_PAINT]请问如何hook其他进程的WM_PAINT

07月 28th, 2008 by admin
Posted in VC/MFC | No Comments »

我要实现在的是给其他程序的一窗口换图,不知是否要拦截系统的wm_paint消息?因刚学hook,不太懂,望得到大家的帮助,最好有相似源码,谢谢!

引用楼主 xyh2009 的帖子:
我要实现在的是给其他程序的一窗口换图,不知是否要拦截系统的wm_paint消息?

用不到hook吧,先找到这个窗口的句柄,再找到这个窗口的客户区或者你想画的DC,接下来直接画上去不久得了?
不是很明白你的需求。

引用 2 楼 zzultc 的回复:
引用楼主 xyh2009 的帖子:
我要实现在的是给其他程序的一窗口换图,不知是否要拦截系统的wm_paint消息?

用不到hook吧,先找到这个窗口的句柄,再找到这个窗口的客户区或者你想画的DC,接下来直接画上去不久得了?
不是很明白你的需求。

那样画上去的图在窗口重绘时会被擦除!

up

那就每隔一段时间重画上去!做个定时器。

方法如下:
写一个DLL注入到目的进程中
在DLL_PROCESS_ATTACH中
开启线程
找到窗口句柄
setwindowlong替换掉窗口的窗口过程
在你的窗口过程中
拦截WM_PAINT消息
不要忘了调用原来的窗口过程

引用 6 楼 nevergone 的回复:
方法如下:
写一个DLL注入到目的进程中
在DLL_PROCESS_ATTACH中
开启线程
找到窗口句柄
setwindowlong替换掉窗口的窗口过程
在你的窗口过程中
拦截WM_PAINT消息
不要忘了调用原来的窗口过程

这个方面应该可行ⷯ𜁼/td>

我那种方法主动防御会报就是了
代码我有实现过
绝对可行

引用 6 楼 nevergone 的回复:
方法如下:
写一个DLL注入到目的进程中
在DLL_PROCESS_ATTACH中
开启线程
找到窗口句柄
setwindowlong替换掉窗口的窗口过程
在你的窗口过程中
拦截WM_PAINT消息
不要忘了调用原来的窗口过程

我那种方法主动防御会报就是了
代码我有实现过
绝对可行

谢谢大家!

Tags: , , ,

[进程][注入][进程]EXE进程如何注入EXE进程

07月 24th, 2008 by admin
Posted in VC/MFC | No Comments »

EXE进程如何注入EXE进程?
问题是:a.exe某线程要注入到b.exe中执行,不是DLL注入EXE啊
请给个演示或资料呀
G.cn了N次也没类似的解决方案
请赐教

可以参考病毒的那种方式,把dll放到exe的资源或类似的地方,然后运行期从资源读取出来,写到临时文件
不知道能不能只放在内存里,没试过

http://blog.csdn.net/singlerace/archive/2006/11/10/1376424.aspx
看下

用EXE比较复杂,主要是进程间的虚拟地址是重叠的,注入代码不能覆盖目标进程的代码,所以只能注入到与原本不同的虚拟地址上,这样所有直接寻址的指令都会出错,要避免使用直接寻址或者用代码修正使用直接寻址的指令。避免直接寻址的做法是:要注入的代码中,不要使用全局变量、静态变量、字符串常量,不要隐式调用DLL中的函数,目前只想到这些,可能有所遗漏。修正指令更加复杂,尽量不要用这种方式。理解上述做法需要有一定的汇编语言基础。

注入的方法是:OpenProcess打开目标进程,VirtualAllocEx在目标进程中分配内存,WriteProcessMemory将要注入的代码和要传送的数据复制过去,然后CreateRemoteThread或者用其它方式使注入的代码等到执行。

typedef struct _RemotePara{
    char pMessageBox[12];
    DWORD dwMessageBox;
}RemotePara;

DWORD __stdcall ThreadProc (RemotePara *lpPara)
{
    typedef int (WINAPI *MMessageBoxA)(HWND,LPCTSTR,LPCTSTR,DWORD);
    MMessageBoxA myMessageBoxA;
    myMessageBoxA =(MMessageBoxA) lpPara->dwMessageBox ;
//    myMessageBoxA(NULL,lpPara->pMessageBox ,lpPara->pMessageBox,0);
 
    return 0;
}

DWORD __stdcall ThreadProc (RemotePara *lpPara)
{

  MessageBoxA(NULL,lpPara->pMessageBox ,lpPara->pMessageBox,0);
LoadLibrary("kernel32.dll");
    return 0;
}

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
{

    const DWORD THREADSIZE=1024;
    DWORD byte_write;

    HWND hWnd = FindWindow("SciCalc","计算器");
    if(!hWnd) return 1;

    DWORD dwProcessId = 0;
    GetWindowThreadProcessId(hWnd, &dwProcessId);
    HANDLE hRemoteProcess = OpenProcess
                (PROCESS_ALL_ACCESS,FALSE,dwProcessId);
    if(!hRemoteProcess) return 1;
    void *pRemoteThread =VirtualAllocEx(hRemoteProcess,0, THREADSIZE,
          MEM_COMMIT &brvbar MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    if(!pRemoteThread)return 1;
    if(!WriteProcessMemory(hRemoteProcess,
        pRemoteThread,(void *)&ThreadProc,THREADSIZE,0)) return 1;

    RemotePara myRemotePara;
    ZeroMemory(&myRemotePara,sizeof(RemotePara));
    HINSTANCE hUser32 = LoadLibrary ("user32.dll");
    myRemotePara.dwMessageBox =(DWORD)
              GetProcAddress (hUser32 , "MessageBoxA");
    strcat(myRemotePara.pMessageBox,"hello");

    RemotePara *pRemotePara =(RemotePara *) VirtualAllocEx(hRemoteProcess ,0,
        sizeof(RemotePara),MEM_COMMIT,PAGE_READWRITE);
    if(!pRemotePara) return 1;
    if(!WriteProcessMemory (hRemoteProcess ,pRemotePara,
        &myRemotePara,sizeof myRemotePara,0))return 1;
   
    // 启动线程.
    HANDLE hThread = CreateRemoteThread(hRemoteProcess ,0,0,
        (LPTHREAD_START_ROUTINE)pRemoteThread ,pRemotePara,0,&byte_write);

    }
非DLL注入方式,比较麻烦

学习。。。

EXE进程的线程注入到另一个EXE进程中,没有人愿意帮我吗
RMB求解,提供一个DEMO就行,各位联系我啊
QQ:五九五九344

没有人能给指导指导吗

你的意思是用工具完成呢还是要编程完成呢??

自己载入exe, 注入到空壳exe
http://blog.csdn.net/zzz3265/archive/2007/10/14/1824662.aspx

学习

学习……..

如果你看不懂我在4楼的回复,恐怕即使有例子也难以实现自己的目的。

我成功啦弟兄们,我成功啦
特别感谢名单:4楼和5楼
哈哈,真爽呀

Tags: ,

[进程][户名]即获取进程用户名

07月 19th, 2008 by admin
Posted in VC/MFC | No Comments »

我用LookupAccountSid(NULL,pTokenUser->User.Sid,szUserName,&dwNameSize,szDomain,&dwDomainSize,&SNU);
(就是进程管理器显示的User Name)

能获取本机管理员用户名字也能获取System用户名字,但是NETWORK SERVICE和LOCAL SERVICE却不能获取,检查得出访问权限不够

贴出我的提升权限函数:
BOOL CALLBACK EnablePrivilege(LPCTSTR lpszPrivilegeName,BOOL bEnable)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES &brvbar
        TOKEN_QUERY &brvbar TOKEN_READ,&hToken))
        return FALSE;
    if(!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))
        return TRUE;

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;

    AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);

    CloseHandle(hToken);

    return (GetLastError() == ERROR_SUCCESS);
}

获取进程用户函数:
LPCTSTR GetProcessUserName(DWORD dwID) // 进程ID
{
HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwID);
if( hProcess==NULL )
return NULL;

HANDLE hToken =NULL;
BOOL bResult =FALSE;
DWORD dwSize =0;

static TCHAR szUserName[256]={0};
TCHAR szDomain[256]={0};
DWORD dwDomainSize=256;
DWORD dwNameSize=256;

SID_NAME_USE    SNU;
PTOKEN_USER pTokenUser=NULL;
__try
{
if( !OpenProcessToken(hProcess,TOKEN_QUERY,&hToken) )
{
bResult = FALSE;
__leave;
}

if( !GetTokenInformation(hToken,TokenUser,pTokenUser,dwSize,&dwSize) )
{
if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
bResult = FALSE ;
__leave;
}
}

pTokenUser = NULL;
pTokenUser = (PTOKEN_USER)malloc(dwSize);
if( pTokenUser == NULL )
{
bResult = FALSE;
__leave;
}

if( !GetTokenInformation(hToken,TokenUser,pTokenUser,dwSize,&dwSize) )
{
bResult = FALSE;
__leave;
}

if( LookupAccountSid(NULL,pTokenUser->User.Sid,szUserName,&dwNameSize,szDomain,&dwDomainSize,&SNU) != 0 )
{
return szUserName;
}
}
__finally
{
if( pTokenUser!=NULL )
free(pTokenUser);
}

return NULL;
}

怎么样提升权限才能获取到另外的用户名?

我不知道…

顶起来~!

Tags: , ,