📄 memscan.c
字号:
if (*regiontype==PAGE_EXECUTE_READ)
{
if ((PPTE->RW==0) || ((PPTE->P==0) && (PPTE->A2==1) )) //read only or paged to disk (lets assume that the protection follows (just a gues)
{
// for undetect... start.
*memorysize+=0x400;
*memorysize-=0x200;
*memorysize+=0x800;
// for undetect... end.
//*memorysize+=0x1000;
}
else
{
//if it's writable
//or if it's not paged and the global bit is on
//then it isn't read-only
EverythingOK=FALSE;
break;
}
}
(UINT_PTR)PPTE=(UINT_PTR)PPTE+PTESize;
}
if (!EverythingOK) break;
}
}
else
{
//4MB of non paged memory
if (*regiontype==PAGE_NOACCESS)
{
// for undetect... start.
*memorysize+=13;
*memorysize+=PAGE_SIZE_LARGE; //increase the size of page_noaccess memory with 4 MB
*memorysize-=13;
// for undetect... end.
}
else
break; //no, the previous wasn't PAGE_NOACCESS so break with the current length
}
(UINT_PTR)PPDE=(UINT_PTR)PPDE+PTESize;
(UINT_PTR)PPTE=((UINT_PTR)(PPDE)-0xc0000000)/PTESize*0x1000; //point to the first PTE of the new PDE
}
// WEnd.
if ((UINT_PTR)PPDE>=MAX_PDE_POS)
ntStatus=STATUS_UNSUCCESSFUL;
}
__finally
{
KeDetachProcess();
}
}
__except(1)
{
//DbgPrint("Exception in GetMemoryRegionData\n");
ntStatus=STATUS_UNSUCCESSFUL;
}
if (PEProcess==NULL) //no valid peprocess was given so I made a reference, so lets also dereference
ObDereferenceObject(selectedprocess);
return NT_SUCCESS(ntStatus);
}
#ifdef CETC
//ooh woot, some real public CETC code.....
char ScanresultBuffer[4096];
int ScanresultBufferPos=0;
VOID FlushScanresultBuffer(void)
{
Send(ScanresultBuffer,ScanresultBufferPos);
ScanresultBufferPos=0;
}
VOID ScanResult(ULONG Address,int Size)
{
char *output;
if (Size>=4096)
return; //error, there's no fucking reason to do a scan like this....
if ((ScanresultBufferPos+Size+6)>=4096)
FlushScanresultBuffer();
ScanresultBuffer[ScanresultBufferPos]=SC_ScanResult; //address:dword; valuesize:byte; value:array of bytes
*(PULONG)(&ScanresultBuffer[ScanresultBufferPos+1])=Address;
__try
{
ScanresultBuffer[ScanresultBufferPos+5]=(BYTE)Size;
RtlCopyMemory(&ScanresultBuffer[ScanresultBufferPos+6],(PVOID)Address,Size);
}
__except(1)
{
//(unreadable)
}
//increase counter with 6+size
ScanresultBufferPos+=6+Size;
}
VOID ScanResultCount(INT64 errorcode)
{
char output[9];
output[0]=SC_ScanResultCount;
*(PINT64)(&output[1])=errorcode;
Send(output,9);
}
VOID UpdateProgressBar(DWORD max,DWORD pos)
{
//in case of network scan send , else set global var and let the usermode app poll
char output[9];
DWORD a=max / 2;//this way even if you go over 80000000 (signed negative) it wont go wrong
DWORD b=pos / 2;
output[0]=SC_UpdateProgressbar;
*(PDWORD)(&output[1])=a;
*(PDWORD)(&output[5])=b;
Send(output,9);
}
VOID FixFPUcrash(void)
{
__try
{
DWORD New8087CW=0x133f; //fuck floating point exceptions
PDWORD PtoNew8087CW=&New8087CW;
//DbgPrint("Going to set the ControlWord of the FP-Coprocessor\n");
_asm
{
FNCLEX
FLDCW [PtoNew8087CW]
}
}
__except(1)
{
//bleh
}
}
VOID UnknownInitialValueScan(IN PVOID StartContext)
{
__try
{
__try
{
//this is a unknown initial value scan.
}
__finally
{
CurrentScan.scanning=FALSE;
CurrentScan.ThreadActive=FALSE;
PsTerminateSystemThread(STATUS_SUCCESS);
}
}
__except(1)
{
//nothing, just go on...
}
}
VOID FirstScanThread(IN PVOID StartContext)
{
KAPC_STATE apc_state;
BYTE bytevalue;
WORD wordvalue;
DWORD dwordvalue;
float floatvalue; //yes, float. I know... don't use them. but this is intended for winxp, and even runs in it's own thread
double doublevalue;
INT64 int64value;
char* stringvalue;
BYTE *ValueList0=NULL;
WORD *ValueList1=NULL;
DWORD *ValueList2=NULL;
float *ValueList3=NULL;
double *ValueList4=NULL;
INT64 *ValueList6=NULL;
DWORD *AddressList=NULL;
int AddressListSize=0;
int found=0,foundsaved=0;
BOOLEAN error=FALSE;
BYTE errorcode=-1; //none set
PVOID mempointer;
MEMREGION *memoryregion=NULL;
int memoryregionsize=0;
int memoryregionentries=0;
int i;
IO_STATUS_BLOCK iosb;
NTSTATUS ntStatus;
BOOLEAN FastScan=((CurrentScan.ScanOptions & SO_FASTSCAN)!=0);
//this thread scans the memory till it is done scanning or till Scanning equals FALSE
//there will be a periodic scan for the state of Scanning
//DbgPrint("This is the FirstScanThread\n");
CurrentScan.ThreadActive=TRUE;
FixFPUcrash();
__try
{
ntStatus=CETC_CreateFile(&addressfile,L"\\DosDevices\\C:\\ADDRESS.DAT");
if (!NT_SUCCESS(ntStatus)) return;
ntStatus=CETC_CreateFile(&valuefile,L"\\DosDevices\\C:\\VALUES.DAT");
if (!NT_SUCCESS(ntStatus)) return;
if (!CurrentScan.scanning) return;
errorcode=SE_IncorrectType;
//DbgPrint("Checking memory type\nVartype=%d\n",CurrentScan.Vartype);
//Allocate memory for the addresslist
AddressList=ExAllocatePoolWithTag(PagedPool,MemscanOptions.buffersize/4,0);
if (AddressList==NULL)
{
//DbgPrint("Failed to allocate memory for the AddressList\n");
return;
}
else
AddressListSize=MemscanOptions.buffersize/4;
#define InitializeList(nr,varsize,value,type) { \ /*
DbgPrint("case "#nr"\n");\ */
if (CurrentScan.scanvaluelength==varsize)\
{\
value=*(##type)(CurrentScan.scanvalue);\
if (CurrentScan.Scantype==ST_Exact_value)\
{\
ValueList##nr=ExAllocatePoolWithTag(PagedPool,AddressListSize*varsize,0);\
if (ValueList##nr==NULL) \
{\ /*
DbgPrint("Failed to allocate memory for ValueList"#nr"\n");\ */
return;\
}\
}\
}\
else\
error=TRUE;\
}
//initialize the list to put the values in
switch (CurrentScan.Vartype)
{
case 0:
{
//initialize the list for the byte value
InitializeList(0,1,bytevalue,PBYTE);
break;
}
case 1:
{
InitializeList(1,2,wordvalue,PWORD);
break;
}
case 2:
{
InitializeList(2,4,dwordvalue,PDWORD);
break;
}
case 3:
{
InitializeList(3,4,floatvalue,PFLOAT);
break;
}
case 4:
{
InitializeList(4,8,doublevalue,double*);
break;
}
case 6:
{
InitializeList(6,8,int64value,PINT64);
break;
}
case 7:
{
//string
//DbgPrint("case 7\n");
if (CurrentScan.scanvaluelength>1)
{
stringvalue=CurrentScan.scanvalue; //just give it the pointer
CETC_Write(valuefile,stringvalue,CurrentScan.scanvaluelength,&iosb);
}
else
error=TRUE;
break;
}
default:
{
//not implemented yet
//DbgPrint("case default\n");
errorcode=SE_NotSupported;
error=TRUE;
}
}
if (error)
{
ScanResultCount(errorcode); //send a error count
return;
}
//DbgPrint("Trying to attach to process\n");
KeAttachProcess((PEPROCESS)CurrentScan.process);
__try
{
DWORD regiontype=0;
DWORD memorysize=0x1234;
DWORD TotalSize=0;
DWORD BytesRead=0;
//DbgPrint("Inside the context of the process I hope\n");
//first time go through to find out the memorysize of the memory to scan
//by default allocate space for 512 entries (one page)
memoryregion=ExAllocatePoolWithTag(PagedPool,512*sizeof(MEMREGION),0);
if (memoryregion==NULL)
{
//DbgPrint("Failed to allocate memory for the memoryregions\n");
return;
}
else
memoryregionsize=512; //512 entries
__try
{
DWORD baseaddress;
mempointer=(PVOID)CurrentScan.Start;
while (((ULONG)mempointer<CurrentScan.Stop) && (GetMemoryRegionData(0,CurrentScan.process,mempointer,®iontype,&memorysize,&baseaddress)))
{
BOOLEAN ok=FALSE;
if (regiontype != PAGE_NOACCESS)
{
if ((CurrentScan.ScanOptions & SO_READONLY)==0)
{
/*
skip readonly
only allow:
PAGE_READWRITE
PAGE_WRITECOPY
PAGE_EXECUTE_READWRITE
PAGE_EXECUTE_WRITECOPY
*/
if ((regiontype == PAGE_READWRITE) ||
(regiontype == PAGE_WRITECOPY) ||
(regiontype == PAGE_EXECUTE_READWRITE) ||
(regiontype == PAGE_EXECUTE_WRITECOPY))
{
ok=TRUE;
}
}
else
{
ok=TRUE;
}
}
if (ok)
{
TotalSize+=memorysize;
//DbgPrint("%d:memorysize=%x - new TotalSize=%x\n",memoryregionentries,memorysize,TotalSize);
if (memoryregionentries>=memoryregionsize) //should never be able to go above, but lets check it anyhow...
{
MEMREGION *newmemoryregion;
//allocate another 512 entries
//DbgPrint("Need more regions\n");
newmemoryregion=ExAllocatePoolWithTag(PagedPool,(memoryregionsize+512)*sizeof(MEMREGION),0);
if (newmemoryregion!=NULL)
{
//copy the old memory to the new one and free the old one
RtlCopyMemory(newmemoryregion,memoryregion,memoryregionsize*sizeof(MEMREGION));
ExFreePool(memoryregion);
memoryregion=newmemoryregion;
memoryregionsize+=512;
}
else
{
ExFreePool(memoryregion);
memoryregion=NULL;
//DbgPrint("Failed to re-allocate memory for the memoryregions\n");
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
};
memoryregion[memoryregionentries].BaseAddress=baseaddress;
memoryregion[memoryregionentries].Size=memorysize;
memoryregionentries++;
}
(ULONG)mempointer+=memorysize;
}
if (memoryregionentries>0)
{
//DbgPrint("Adjusting regions\n");
//DbgPrint("before:TotalSize=%x\nmemoryregion[0].BaseAddress=%x\n",TotalSize,memoryregion[0].BaseAddress);
//adjust start and stop
if (memoryregion[0].BaseAddress<CurrentScan.Start)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -