首页
社区
课程
招聘
[求助]请问如何能解析到正在运行进程的PE信息
发表于: 2007-12-4 09:11 12674

[求助]请问如何能解析到正在运行进程的PE信息

2007-12-4 09:11
12674
RT,例如:Process a.exe is running.Now How can I recieve the a.exe file information.

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (29)
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
2
1.使用GetModuleHandle 获得hModule;

2.hModule指向的就是PE文件的DOS HEADER。

3。根据PE文件结构,从hModule指向的地址,开始读取。。。
2007-12-4 10:39
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
3
两种途径:
1。进程内工作。例如注入dll。
2。进程外工作。通过OpenProcess,ReadProcessMemory等API.
2007-12-4 10:44
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
如果
HANDLE hProc = OpenProcess("[System]");
HANDLE hBase = GetModuleHandle(hProc);
//返回值总为0且126 = GetLastError()
如果这么修改
HANDLE hProc = OpenProcess("[System]");
GetModuleFileName((HMODULE)hProc,chTmp,sizeof(chTmp));
//由于System Handle == 0 所以这里得到的永远都是当前进程的运行路径
hBaseAddr = GetModuleHandle(chTmp);
//这里得到是当前进程的那个HANDLE
这样导致了漏掉了System HANDLE
还有如果hBaseAddr为DOS HEADER那么是不是
ReadProcessMemory(hProc,hBaseAddr,szBuf,sizeof(IMAGE_DOS_HEADER));
便可以得到该Process的Dos Header?
2007-12-5 15:50
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
现在可以得到系统的进程表但是却总得不到进程的PE基址信息。
例如:
//这里的m_process.szExeFile == smss.exe
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,m_process.th32ProcessID);
//无法得到该ModuleFileName
GetModuleFileName((HMODULE)hProc,chTmp,sizeof(chTmp));
//所以这里
GetModuleHandle(chTmp)
//总是错误
2007-12-5 17:27
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
来人帮帮忙啊!
2007-12-5 17:30
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
7
system进程 PID 是 4,这个进程你放弃吧。
2007-12-5 17:43
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
1.最好先增加调试特权再打开系统进程。
2.System并不对应可执行文件,它是系统特殊线程的母体。
2007-12-5 20:33
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
虽说我不是什么老鸟但这点偶还是知道的
LRESULT CMainDlg::SetupRight(const char *lpszPrivilegesName)
{
        TOKEN_PRIVILEGES tkp = { 0 };
        HANDLE hToken = NULL;
        if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
                return E_FAIL;
        if(!LookupPrivilegeValue(NULL,lpszPrivilegesName,&tkp.Privileges[0].Luid))
                return E_FAIL;
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
                return E_FAIL;
        return S_OK;
}
2007-12-6 08:37
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
偶只是说一下我的意见,并没有其它意思。
2007-12-6 08:42
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
源码如下:
while(lpHelp->EnumProcess(&m_process))
{
      HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,m_process.th32      ProcessID);               
      ZeroMemory(chTmp,sizeof(chTmp));
      GetModuleFileName((HMODULE)hProc,chTmp,sizeof(chTmp));
      hBaseAddr = GetModuleHandle(chTmp);
     //如果hBaseAddr为Dos Header基址
    IMAGE_DOS_HEADER *lpDos = new IMAGE_DOS_HEADER;
     ZeroMemory(lpDos,sizeof(IMAGE_DOS_HEADER));
     DWORD dwReaded = 0;
     unsigned char *lpBytes = new unsigned char[50];
     if(ReadProcessMemory(hProc,hBaseAddr,lpBytes,sizeof(unsigned char)*50,&dwReaded))
    {
          if(dwReaded != sizeof(IMAGE_DOS_HEADER))
        dwError = GetLastError();
   }
   else
   {
          if(dwReaded != sizeof(IMAGE_DOS_HEADER))
        dwError = GetLastError();       
    }
        。。。
}
运行到smss.exe进程的时候能得到该进程的绝对路径但是却得不到该Module HANDLE也就得不到基址,请问大家有什么办法解决
2007-12-6 08:51
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
dwReaded = VirtualQueryEx(hProc,0x00000000,&memInfo,sizeof(MEMORY_BASIC_INFORMATION));
可以得到smss.exe的虚拟内存信息但是如果我打算修改其保护属性
如:dwReaded = VirtualProtectEx(hProc,0x00000000,1024,PAGE_EXECUTE_WRITECOPY,&dwOldProtected);
告诉我句柄错误,TMD老子都能Query到修改的时候却告诉我句柄错误。
2007-12-6 10:11
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
DWORD JToolHelp::GetAllProcessUser(HANDLE hProc,char *lpUserName,char *lpDomain,DWORD dwUserSize,DWORD dwDomainSize,char *lpSystemName)
{
        if(lpUserName ==NULL||lpDomain == NULL)
                return 0x0000FFFF;
        //取得TokenInformation需要的内存长度
        HANDLE hToken = NULL;
        SID_NAME_USE SidType;
        TOKEN_USER *pTokenUser = NULL;
        __try
        {
                if(!OpenProcessToken(hProc,TOKEN_QUERY,&hToken))
                {
                        return 0x0000000F;
                }
                DWORD dwLength = 0;
               
                GetTokenInformation(hToken,TokenUser,NULL,dwLength,&dwLength);
                pTokenUser = (TOKEN_USER*)LocalAlloc(LPTR,dwLength);
                if(!GetTokenInformation(hToken,TokenUser,pTokenUser,dwLength,&dwLength))
                        __leave;
                if(!LookupAccountSid(lpSystemName,pTokenUser->User.Sid,lpUserName,&dwUserSize,lpDomain,&dwDomainSize,&SidType))
                        __leave;
        }
        __finally
        {
                if(hToken != NULL)
                {
                        CloseHandle(hToken);       
                }
                if(pTokenUser != NULL)
                {
                        LocalFree(pTokenUser);
                        OutputDebugString("\r\nLocalFree\r\n");
                }
        }
        return GetLastError();
}
以上代码只能取得部分进程的所属用户但是例如alg.exe,svchost.exe却不可以。
请问为什么?还有什么更好的解决方案
0x000000040也不能取得其所属用户。
2007-12-6 11:49
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
14
因为像alg.exe,svchost.exe这些进程默认是没有SeCreateTokenPrivilege权限的。
2007-12-6 13:27
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
15
NT的安全组件里有一个叫Local Security Authority Protected Subsystem.当我们以ADMINISTRATOR登陆时,系统根据缺省的授权,赋予ADMINISTRATOR16个授权.下面乃是详细的清单.
SeChangeNotifyPrivilege
SeSecurityPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeSystemtimePrivilege
SeShutdownPrivilege
SeRemoteShutdownPrivilege
SeTakeOwnershipPrivilege
SeDebugPrivilege
SeSystemEnvironmentPrivilege
SeSystemProfilePrivilege
SeProfileSingleProcessPrivilege
SeIncreaseBasePriorityPrivilege
SeLoadDriverPrivilege
SeCreatePagefilePrivilege
SeIncreaseQuotaPrivilege
其中 SeChangeNotifyPrivilege是缺省打开的.其他则需要调整TOKEN来打开.拥有了这么多的权限后,ADMIN真可谓强大,没有任何其他用户拥有这么多的权限了.但是,仍然有几个更有威力的权限没有赋予ADMIN.那就是SeTcbPrivilege和 SeCreateTokenPrivilege. SeTcbPrivilege表示当前用户的操作代表了系统的操作,SeCreateTokenPrivilege更可赤裸裸地为任意令牌创建权限.乃是无上的特权。

由于没有直接的API可以增加TOKEN的特权,我们只好通过LSA POLICY库调整用户权限.因为用户权限在LSA POLICY库里被提取出来.当LSA POLICY库里增加了一个特权,用户可以在下一个进程里打开该特权。

下面的代码就是给admin用户增加一个SeCreateTokenPrivilege权限。
#define UNICODE
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <ntsecapi.h>

//
//Global vars
//
LSA_HANDLE PolicyHandle;
PSID Sid=0;
DWORD cbSid=0;
LPTSTR ReferencedDomainName=0;
DWORD cbReferencedDomainName=0;
SID_NAME_USE peUse;
PUNICODE_STRING UserRights=0; //UnicodeString Pointer to PRIVILEGE
ULONG Count=0; //
WCHAR textSid[200];
HANDLE token=0;
PTOKEN_PRIVILEGES TokenInformation=0;
BOOL owned=0;

//
//quit
//
void quit(int err)
{
        if (Sid)
                delete Sid;
        if (ReferencedDomainName)
                delete ReferencedDomainName;
        if (UserRights)
                delete UserRights;
        if (TokenInformation)
                delete TokenInformation;
        if (token)
                CloseHandle(token);
        if (PolicyHandle)
                LsaClose(PolicyHandle);

        if (err)
        {
                exit(0xc0000000);
        }
        else
        {
                exit(0);
        }
}

void printprivilege(LUID_AND_ATTRIBUTES* luid)
{
        WCHAR dispname[100];
        ULONG cb=100;

        if (!LookupPrivilegeName(
                                                        0,
                                                        &(luid->Luid),
                                                        dispname,
                                                        &cb))
        {
                wprintf(L"I can't translate SOME LUID to privilege!\n");
                exit(1);
        }

        wprintf(L"\tPrivilege: %s\n",dispname);

        if (!_wcsicmp(dispname,L"SeCreateTokenPrivilege"))
                owned=1;

        switch (luid->Attributes)
        {
        case SE_PRIVILEGE_ENABLED_BY_DEFAULT:
                wprintf(L"\t\tThis privilege is enabled by default\n");
                break;
        case SE_PRIVILEGE_ENABLED:
                wprintf(L"\t\tThis privilege is enabled.\n");
                break;
        case SE_PRIVILEGE_USED_FOR_ACCESS:
                wprintf(L"\t\tThis privilege is used for access.\n");
                break;
        case 3:
                wprintf(L"\t\tThis privilege is always on for you.\n");
                break;
        case 0:
                wprintf(L"\t\tThis privilege you owned has not been enabled yet.\n");
        }
}

void init()
{
        WCHAR username[30];
        ULONG cb;
        OSVERSIONINFO osv;

        ZeroMemory(&osv,sizeof(osv));
        osv.dwOSVersionInfoSize=sizeof(osv);
        GetVersionEx(&osv);
        if (!osv.dwPlatformId&VER_PLATFORM_WIN32_NT)
        {
                wprintf(L"This program only runs on NT");
                quit(1);
        }

        //
        //Check if this thread is executed inside administrator's context.
        //
        cb=30;
        GetUserName(username,&cb);
        if (_wcsicmp(username,L"administrator"))
        {
                wprintf(L"Logon as administrator first!\n");
                quit(1);
        }

        wprintf(L"WINDOWS NT %i.%i Build %i %s\n\n",
                                osv.dwMajorVersion,
                                osv.dwMinorVersion,
                                osv.dwBuildNumber,
                                osv.szCSDVersion);
}

BOOL GetTextualSid(
                                PSID pSid, // binary Sid
                                LPTSTR TextualSid, // buffer for Textual representation of Sid
                                DWORD dwBufferLen // required/provided TextualSid buffersize
                                )
{
        PSID_IDENTIFIER_AUTHORITY psia;
        DWORD dwSubAuthorities;
        DWORD dwSidRev=SID_REVISION;
        DWORD dwCounter;
        DWORD dwSidSize;

        // Validate the binary SID.

        if(!IsValidSid(pSid))
                return FALSE;

        // Get the identifier authority value from the SID.
        psia = GetSidIdentifierAuthority(pSid);

        // Get the number of subauthorities in the SID.
        dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

        // Compute the buffer length.
        // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
        dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

        // Check input buffer length.
        // If too small, indicate the proper size and set last error.
        if (dwBufferLen < dwSidSize)
        {
                SetLastError(ERROR_INSUFFICIENT_BUFFER);
                return FALSE;
        }

        // Add 'S' prefix and revision number to the string.
        dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );

        // Add SID identifier authority to the string.
        if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
        {
                dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                                                        TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                                                        (USHORT)psia->Value[0],
                                                        (USHORT)psia->Value[1],
                                                        (USHORT)psia->Value[2],
                                                        (USHORT)psia->Value[3],
                                                        (USHORT)psia->Value[4],
                                                        (USHORT)psia->Value[5]);
        }
        else
        {
                dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                                                        TEXT("%lu"),
                                                        (ULONG)(psia->Value[5] ) +
                                                        (ULONG)(psia->Value[4] << 8) +
                                                        (ULONG)(psia->Value[3] << 16) +
                                                        (ULONG)(psia->Value[2] << 24) );
        }

        // Add SID subauthorities to the string.
        //
        for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
        {
                dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
                *GetSidSubAuthority(pSid, dwCounter) );
        }

        return TRUE;
}

void main()
{
        LSA_OBJECT_ATTRIBUTES ObjectAttributes;
        ZeroMemory(&ObjectAttributes,sizeof(ObjectAttributes));

        init();
        //
        //First open LSA policy database
        //the call returns a NTSTATUS. NTSTATUS 0 means everything is OK.
        //
        if (LsaOpenPolicy(
                                                0,
                                                &ObjectAttributes,
                                                GENERIC_EXECUTE|GENERIC_READ|GENERIC_WRITE,
                                                &PolicyHandle
                                                ))
        {
                wprintf(L"Open Policy error!\n");
        }
        else
        {
                Sid=new char[500];
                ReferencedDomainName=new WCHAR[100];
                cbSid=500;
                cbReferencedDomainName=100;

                //
                //Show Administrator SID
                //
                if (!LookupAccountName(
                                                                0,
                                                                L"Administrator",
                                                                Sid,
                                                                &cbSid,
                                                                ReferencedDomainName,
                                                                &cbReferencedDomainName,
                                                                &peUse
                                                                ))
                {
                        wprintf(L"Damn, I can't find out the account looking for!\n");
                        quit(1);
                }
                if (!GetTextualSid(Sid,textSid,200))
                {
                        wprintf(L"Damn, Get textual SID error! Maybe a bug in this program.\n");
                        quit(1);
                }

                wprintf(L"The SID of administrator is: %s \n",textSid);
                wprintf(L"\tOn the server: %s\n",ReferencedDomainName);

                //
                //Check current privilege
                //
                if (!OpenProcessToken(
                                                                GetCurrentProcess(),
                                                                TOKEN_QUERY,
                                                                &token))
                {
                        wprintf(L"Can't open process token! What's happened?\n");
                        quit(1);
                }

                TokenInformation=(PTOKEN_PRIVILEGES)(new char[2000]);

                if (!GetTokenInformation(
                                                                token,
                                                                TokenPrivileges,
                                                                (void*)TokenInformation,
                                                                2000,
                                                                &cbSid //Note, Returned lenght of token information.
                                                                ))
                {
                        wprintf(L"Can't get token information\n");
                        quit(1);
                }
                else
                {
                        LUID_AND_ATTRIBUTES *luid;
                        luid=(LUID_AND_ATTRIBUTES *)&TokenInformation->Privileges;

                        wprintf(L"\nTotal privilege count: %i\n\n",TokenInformation->PrivilegeCount);
                        for (Count=0;Count<TokenInformation->PrivilegeCount;Count++,luid++)
                        {
                                printprivilege(luid);
                        }
                }

                //
                //Add SeCreateTokenPrivilege to Administrator if not owned yet!
                //
                if (!owned)
                {
                        UserRights=new LSA_UNICODE_STRING;
                        UserRights->Buffer=L"SeCreateTokenPrivilege";
                        UserRights->MaximumLength=44;
                        UserRights->Length=44;

                        if (LsaAddAccountRights(
                                                                        PolicyHandle,
                                                                        Sid,
                                                                        UserRights,
                                                                        1
                                                                        ))
                        {
                                wprintf(L"Damn! Add right failed! :(\n");
                                quit(1);
                        }
                        else
                                wprintf(L"\nAdd SeCreateTokenPrivilege successfully!\n");

                        quit(0);
                }
                else
                {
                        wprintf(L"\nYou own SeCreateTokenPrivilege. I don't add it for you.\n");
                }
        }
}
2007-12-6 13:53
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
怎么加声望?
2007-12-6 14:34
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
17
点击每一贴右上角的*号图标。
2007-12-6 14:37
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
非常感谢您的回答!我业已给你加声望。
2007-12-6 14:39
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
加完了请问这个问题怎么解决?
2007-12-6 14:49
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
LRESULT CMainDlg::SetupRight(const char *lpszPrivilegesName)
{
        TOKEN_PRIVILEGES tkp = { 0 };
        HANDLE hToken = NULL;
        if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
                return E_FAIL;
        if(!LookupPrivilegeValue(NULL,lpszPrivilegesName,&tkp.Privileges[0].Luid))
                return E_FAIL;
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
                return E_FAIL;
        return S_OK;
}
请问我如果将Token权限调整为"SeCreateTokenPrivilege" 是否可以得到0x00000040级别进程的信息呢?
但是我发现这个方案失败了
2007-12-6 15:06
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
21
学习  学习
2007-12-6 15:29
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
22
这...这不是Debug权限.请问这是?
2007-12-7 09:00
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
if(!SUCCEEDED(SetupRight("SeCreateTokenPrivilege")))
        {
                ::MessageBox(NULL,"无法获取Debug权限!","提示",MB_OK|MB_ICONSTOP);
                PostQuitMessage(0x0000FFFF);
                return E_FAIL;
        }
源程序是这么调用的
2007-12-7 09:04
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
我感觉不应该是权限的问题
返回值为15
2007-12-7 12:01
0
雪    币: 20
活跃值: (37)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
25
DWORD JToolHelp::GetProcessUser(HANDLE hProc,char *lpUserName,char *lpDomain,DWORD dwUserSize
                                                                   ,DWORD dwDomainSize,char *lpSystemName)
{
        if(lpUserName ==NULL||lpDomain == NULL)
                return 0x0000FFFF;
        //取得TokenInformation需要的内存长度
        HANDLE hToken = NULL;
        SID_NAME_USE SidType;
        TOKEN_USER *pTokenUser = NULL;
        __try
        {
                if(!OpenProcessToken(hProc,TOKEN_QUERY,&hToken))
                {
                        return 0x0000000F;
                }
                DWORD dwLength = 0;
                GetTokenInformation(hToken,TokenUser,NULL,dwLength,&dwLength);
                if(dwLength != 0)
                        pTokenUser = (TOKEN_USER*)LocalAlloc(LPTR,dwLength);
                else
                        __leave;
                if(!GetTokenInformation(hToken,TokenUser,pTokenUser,dwLength,&dwLength))
                        __leave;
                if(!LookupAccountSid(lpSystemName,pTokenUser->User.Sid,lpUserName,&dwUserSize,lpDomain,&dwDomainSize,&SidType))
                        __leave;
        }
        __finally
        {
                if(hToken != NULL)
                {
                        CloseHandle(hToken);       
                }
                if(pTokenUser != NULL)
                {
                        LocalFree(pTokenUser);
                        OutputDebugString("\r\nLocalFree\r\n");
                }
        }
        return GetLastError();
}
以上代码能得到绝大多数的Process User但是对于alg.exe,svchost.exe,system却得不到返回错误代码15
2007-12-7 12:39
0
游客
登录 | 注册 方可回帖
返回
//