瑞星卡卡安全论坛

首页 » 综合娱乐区 » 活动专区 » 实习生专区 » 实习生交流区 » 关于注册表的问题
猎豹一号 - 2008-9-15 16:40:00
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows]
    <load><>  [N/A]

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows]
    <run><>  [N/A]

这两项是干吗的?
我的电脑扫描上有第一项!
我看到有的电脑扫描日记没有这其中两项的一项?
简单问题别见笑!
叶陵君 - 2008-9-15 22:37:00
注册表自启动项,你电脑每次启动,都会启动上面两项相关的程序或动态链接库。你电脑上那一项看下是什么程序。也有正常程序跑那的,很少就是。
猎豹一号 - 2008-9-16 16:00:00


引用:
原帖由 叶陵君 于 2008-9-15 22:37:00 发表
注册表自启动项,你电脑每次启动,都会启动上面两项相关的程序或动态链接库。你电脑上那一项看下是什么程序。也有正常程序跑那的,很少就是。

不明白!能说清楚的吗?
文物2 - 2008-9-17 8:31:00
虽然有疑惑,还不敢妄言:default6:
文物2 - 2008-9-17 8:41:00


引用:

标 题: 【原创】进程中dll模块的隐藏
作 者: NetRoc
时 间: 2008-02-20,17:28
链 接: http://bbs.pediy.com/showthread.php?t=59932


进程中dll模块的隐藏


cc682/NetRoc
http://netroc682.spaces.live.com/
        为了避免自己的某个dll模块被别人检测出来,有时候希望在自己加载一个dll之后,或者将dll注入到他人进程之后避免被检查出来。这就需要想办法抹掉这个dll的模块信息,使得Toolhelp、psapi等枚举模块的API无法枚举它。
        我们可以先简单看看Windows枚举进程内模块的办法吧:
        首先是BOOL EnumProcessModules( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded);
        EnumProcessModules实际调用EnumProcessModulesInternal进行枚举。下面是vista下psapi的代码片断:
.text:514024B8                push    ebx
.text:514024B9                push    18h
.text:514024BB                lea    eax, [ebp+stProcessBasicInfo]
.text:514024BE                push    eax
.text:514024BF                push    ebx  ;ebx=0
.text:514024C0                push    [ebp+hProcess]
.text:514024C3                call    ds:__imp__NtQueryInformationProcess@20 ; NtQueryInformationProcess(x,x,x,x,x)
.text:514024C9                cmp    eax, ebx
.text:514024CB                jge    short loc_514024E0
        调用NtQueryInformationProcess获得ProcessBasicInformation,在PROCESS_BASIC_INFORMATION结构中取得PEB地址。然后读取指定进程PEB中的数据
text:514024E0 loc_514024E0:                          ; CODE XREF: EnumProcessModulesInternal(x,x,x,x,x)+24 j
.text:514024E0                mov    eax, [ebp+stProcessBasicInfo.PebBaseAddress]
.text:514024E3                cmp    eax, ebx
.text:514024E5                jnz    short loc_514024EE
.text:514024E7                push    8000000Dh
.text:514024EC                jmp    short loc_514024CE
.text:514024EE ; ---------------------------------------------------------------------------
.text:514024EE
.text:514024EE loc_514024EE:                          ; CODE XREF: EnumProcessModulesInternal(x,x,x,x,x)+3E j
.text:514024EE                push    ebx            ; lpNumberOfBytesRead
.text:514024EF                push    4              ; nSize
.text:514024F1                lea    ecx, [ebp+Ldr]
.text:514024F4                push    ecx            ; lpBuffer
.text:514024F5                add    eax, 0Ch
.text:514024F8                push    eax            ; lpBaseAddress
.text:514024F9                push    [ebp+hProcess]  ; hProcess
.text:514024FC                mov    edi, ds:__imp__ReadProcessMemory@20 ; ReadProcessMemory(x,x,x,x,x)
.text:51402502                call    edi ; ReadProcessMemory(x,x,x,x,x) ; ReadProcessMemory(x,x,x,x,x)
这里读取的是PEB地址+0C处的四个字节。
通过WinDbg我们可以看看nt!_PEB的结构
0: kd> dt nt!_PEB
  +0x000 InheritedAddressSpace : UChar
  +0x001 ReadImageFileExecOptions : UChar
  +0x002 BeingDebugged    : UChar
  +0x003 SpareBool        : UChar
  +0x004 Mutant          : Ptr32 Void
  +0x008 ImageBaseAddress : Ptr32 Void
  +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
  +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
……
+0C处是一个_PEB_LDR_DATA结构指针,里面包含了和LDR相关的一些数据,进程的模块链表就保存在Ldr中。下面是_PEB_LDR_DATA的结构:
0: kd> dt nt!_PEB_LDR_DATA
  +0x000 Length          : Uint4B
  +0x004 Initialized      : UChar
  +0x008 SsHandle        : Ptr32 Void
  +0x00c InLoadOrderModuleList : _LIST_ENTRY
  +0x014 InMemoryOrderModuleList : _LIST_ENTRY
  +0x01c InInitializationOrderModuleList : _LIST_ENTRY
  +0x024 EntryInProgress  : Ptr32 Void
其中,InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList就是进程当前已加载模块的链表,只是按照不同的方式排序。EnumProcessModules是通过InMemoryOrderModuleList链表枚举的,而根据Win2k代码,ToolHelp32函数是通过InLoadOrderModuleList枚举。这三个_LIST_ENTRY都是在一个RTL_PROCESS_MODULE_INFORMATION结构中的成员。这个结构在2k代码中有引用,不过没有确切的定义,下面是ReactOS中的定义,不过看起来我的vista PSAPI中使用的结构已经有所变化了,这里只作参考。
//
// Loader Data Table Entry
//
typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union
    {
        LIST_ENTRY HashLinks;
        PVOID SectionPointer;
    };
    ULONG CheckSum;
    union
    {
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    };
    PVOID EntryPointActivationContext;
    PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
到这里,隐藏模块的方法就已经明了了:通过PEB取得Ldr数据,拿到三个模块链表,并将要隐藏的模块断链即可。下面是主要代码实现:
BOOL HideMyself()
{
  HMODULE hMod = GetModuleHandle( _T( "ntdll.dll"));
  HMODULE hModMyself = GetModuleHandle( _T("dll.dll"));
  pfnNtQueryInformationProcess p = (pfnNtQueryInformationProcess)::GetProcAddress( hMod, "NtQueryInformationProcess");

  PROCESS_BASIC_INFORMATION stInfo = {0};
  DWORD dwRetnLen = 0;
  DWORD dw = p( GetCurrentProcess(), 0, &stInfo, sizeof(stInfo), &dwRetnLen);

  PPEB pPeb = stInfo.PebBaseAddress;
  PLIST_ENTRY ListHead, Current;
  PLDR_DATA_TABLE_ENTRY pstEntry = NULL;

  ListHead = &( stInfo.PebBaseAddress->Ldr->InLoadOrderModuleList);
  Current = ListHead->Flink;
  while ( Current != ListHead)
  {
    pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
    if ( pstEntry->DllBase == hModMyself)
    {
      pstEntry->InLoadOrderLinks.Flink->Blink = pstEntry->InLoadOrderLinks.Blink;
      pstEntry->InLoadOrderLinks.Blink->Flink = pstEntry->InLoadOrderLinks.Flink;
      DebugOut( _T( "Hide injected dll."));
      break;
    }
    Current = pstEntry->InLoadOrderLinks.Flink;
  }

  ListHead = &( stInfo.PebBaseAddress->Ldr->InMemoryOrderModuleList);
  Current = ListHead->Flink;
  while ( Current != ListHead)
  {
    pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
    DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
    if ( pstEntry->DllBase == hModMyself)
    {
      pstEntry->InMemoryOrderModuleList.Flink->Blink = pstEntry->InMemoryOrderModuleList.Blink;
      pstEntry->InMemoryOrderModuleList.Blink->Flink = pstEntry->InMemoryOrderModuleList.Flink;
      DebugOut( _T( "Hide injected dll."));
      break;
    }
    Current = pstEntry->InMemoryOrderModuleList.Flink;
  }
  DebugOutW( L"\r\n");

  ListHead = &( stInfo.PebBaseAddress->Ldr->InInitializationOrderModuleList);
  Current = ListHead->Flink;
  while ( Current != ListHead)
  {
    pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
    DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
    if ( pstEntry->DllBase == hModMyself)
    {
      pstEntry->InInitializationOrderModuleList.Flink->Blink = pstEntry->InInitializationOrderModuleList.Blink;
      pstEntry->InInitializationOrderModuleList.Blink->Flink = pstEntry->InInitializationOrderModuleList.Flink;
      DebugOut( _T( "Hide injected dll."));
      break;
    }
    Current = pstEntry->InInitializationOrderModuleList.Flink;
  }
  //DebugOut( _T("Out HideMyself\r\n"));
  return TRUE;
}
        这样处理之后,通过常规的枚举进程方式已经枚举不到隐藏模块,ProcessExplorer也无法枚举。但是,通过枚举进程内存空间等非常规方法,仍然是可以找到的。关于PSAPI和Toolhelp函数枚举模块的原理,可以逆向Windows代码,或者查找网上的代码看看就明白了。






引用:

标 题: 【原创】ring0检测隐藏进程
作 者: 堕落天才
时 间: 2007-05-10,13:28
链 接: http://bbs.pediy.com/showthread.php?t=44243

//网上得到一篇好文章 Ring0下搜索内存枚举隐藏进程 ,但是拿里面的代码来使用的时候发现并没有太多效果
//于是修改之,终于实现了最初的目标
//由于直接搜索内存,跟系统调度没什么关系,所以能够枚举到各种方法隐藏的进程 包括断链、抹PspCidTable...
//甚至能枚举到已经"死掉"的进程,本程序通过进程的ExitTime来判断进程是不是已经结束
//除非能够把EProcess结构修改掉,但这个实现难度可能比较大,不知有没有哪位大侠试过(PID我修改过),欢迎讨论
//
//作者:堕落天才
//时间:2007年5月10日
//参考: uty  Ring0下搜索内存枚举隐藏进程 http://www.cnxhacker.net/Article/show/3412.html
//下面代码在XP SP2测试通过


#include<ntddk.h>

///////////////////////////不同的windows版本下面的偏移值不同
#define  EPROCESS_SIZE      0x25C //EPROCESS结构大小

#define  PEB_OFFSET          0x1B0
#define  FILE_NAME_OFFSET    0x174
#define  PROCESS_LINK_OFFSET 0x088
#define  PROCESS_ID_OFFSET  0x084
#define  EXIT_TIME_OFFSET    0x078

#define  OBJECT_HEADER_SIZE  0x018
#define  OBJECT_TYPE_OFFSET  0x008

#define PDE_INVALID 2
#define PTE_INVALID 1
#define VALID 0


ULONG    pebAddress;        //PEB地址的前半部分
PEPROCESS pSystem;            //system进程
ULONG    pObjectTypeProcess; //进程对象类型

ULONG  VALIDpage(ULONG addr) ;  //该函数直接复制自 Ring0下搜索内存枚举隐藏进程
BOOLEAN IsaRealProcess(ULONG i); //该函数复制自 Ring0下搜索内存枚举隐藏进程
VOID    WorkThread(IN PVOID pContext);
ULONG  GetPebAddress();          //得到PEB地址前半部分
VOID    EnumProcess();            //枚举进程
VOID    ShowProcess(ULONG pEProcess); //显示结果

VOID    OnUnload(IN PDRIVER_OBJECT DriverObject)
{
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
  HANDLE hThread;

  DriverObject -> DriverUnload = OnUnload;

  pSystem    = PsGetCurrentProcess();
  pebAddress = GetPebAddress();
  pObjectTypeProcess = *(PULONG)((ULONG)pSystem - OBJECT_HEADER_SIZE +OBJECT_TYPE_OFFSET); 

  PsCreateSystemThread(&hThread,
    (ACCESS_MASK)0,
    NULL,
    (HANDLE)0,
    NULL,
    WorkThread,
    NULL );

  return STATUS_SUCCESS;
}
//////////////////////////////////////////////
VOID WorkThread(IN PVOID pContext)
{
  EnumProcess();
  PsTerminateSystemThread(STATUS_SUCCESS); 
}
////////////////////////////////////////////////////////
ULONG  GetPebAddress()
{
  ULONG Address;
  PEPROCESS pEProcess;

        //由于system进程的peb总是零 我们只有到其他进程去找了
  pEProcess = (PEPROCESS)((ULONG)((PLIST_ENTRY)((ULONG)pSystem + PROCESS_LINK_OFFSET))->Flink - PROCESS_LINK_OFFSET);
  Address  = *(PULONG)((ULONG)pEProcess + PEB_OFFSET);

  return (Address & 0xFFFF0000); 
}
///////////////////////////////////////////////////////
VOID EnumProcess()
{
  ULONG  uSystemAddress = (ULONG)pSystem;
  ULONG  i;
  ULONG  Address;
  ULONG  ret;

  DbgPrint("-------------------------------------------");
  DbgPrint("EProcess    PID    ImageFileName");
  DbgPrint("---------------------------------");
 

  for(i = 0x80000000; i < uSystemAddress; i += 4){//system进程的EPROCESS地址就是最大值了
    ret = VALIDpage(i);
    if (ret == VALID){
      Address = *(PULONG)i;
      if (( Address & 0xFFFF0000) == pebAddress){//每个进程的PEB地址都是在差不多的地方,地址前半部分是相同的     
        if(IsaRealProcess(i)){
          ShowProcess(i - PEB_OFFSET); 
          i += EPROCESS_SIZE;               
        }
      }
    }else if(ret == PTE_INVALID){
      i -=4;
      i += 0x1000;//4k
    }else{
      i-=4;
      i+= 0x400000;//4mb
    }
  }

  ShowProcess(uSystemAddress);//system的PEB总是零 上面的方法是枚举不到的 不过我们用PsGetCurrentProcess就能得到了
  DbgPrint("-------------------------------------------");
 
}
/////////////////////////////////////////////////////////
VOID    ShowProcess(ULONG pEProcess)
{
  PLARGE_INTEGER ExitTime;
  ULONG PID;
  PUCHAR pFileName;
 
  ExitTime = (PLARGE_INTEGER)(pEProcess + EXIT_TIME_OFFSET); 
  if(ExitTime->QuadPart != 0) //已经结束的进程的ExitTime为非零
    return ;

  PID = *(PULONG)(pEProcess + PROCESS_ID_OFFSET);
  pFileName = (PUCHAR)(pEProcess + FILE_NAME_OFFSET);

  DbgPrint("0x%08X  %04d  %s",pEProcess,PID,pFileName);
}
/////////////////////////////////////////////////////////////
ULONG VALIDpage(ULONG addr)
{
  ULONG pte;
  ULONG pde;
 
  pde = 0xc0300000 + (addr>>22)*4;
  if((*(PULONG)pde & 0x1) != 0){
    //large page
    if((*(PULONG)pde & 0x80) != 0){
      return VALID;
    }
    pte = 0xc0000000 + (addr>>12)*4;
    if((*(PULONG)pte & 0x1) != 0){
      return VALID;
    }else{
      return PTE_INVALID;
    }
  }
  return PDE_INVALID;
}
////////////////////////////////////////////////////////////////
BOOLEAN IsaRealProcess(ULONG i)
{
  NTSTATUS STATUS;
  PUNICODE_STRING pUnicode;
  UNICODE_STRING Process;
  ULONG pObjectType;
  ULONG ObjectTypeAddress;
 
  if (VALIDpage(i- PEB_OFFSET) != VALID){
    return FALSE;
  }

  ObjectTypeAddress = i - PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET ;
 
  if (VALIDpage(ObjectTypeAddress) == VALID){
    pObjectType = *(PULONG)ObjectTypeAddress;
  }else{
    return FALSE;
  }
 
  if(pObjectTypeProcess == pObjectType){ //确定ObjectType是Process类型
    return TRUE;
  }
  return FALSE;

}
////////////////////////////////////////////////////////////////////




文物2 - 2008-9-17 8:51:00
注册表信息隐藏

http://bbs.pediy.com/showthread.php?t=63540
猎豹一号 - 2008-9-17 8:54:00
:default20: 连代码都拿出来了?值得研究研究!
文物2 - 2008-9-17 10:15:00
这里需要研究一下:default6:
1
查看完整版本: 关于注册表的问题