Rootkits: Subverting the Windows Kernel [Source/PDF]

This is an extremely useful book on rootkits: Rootkits: Subverting the Windows Kernel

PDF: http://micropenguin.net/files/Other/Rootkits_Subverting_the_Windows_Kernel.pdf

It took me awhile to find all of the source code examples in the book. Since rootkit.com has been taken down, and that is where the book directs you to download from.

These are the examples listed in the book:

InstDrv.zip
migbot.zip
basic_1.zip
basic_hardware.zip
basic_keysniff.zip
HideProcessHookMDL.zip
HybridHook.zip
Klog 1.0.zip
rk_044.zip
strace_Fuzen.zip
SysEnterHook.zip
vice.zip

HaleOS

Development of a simple x64 bit operating system is now in progress! Matt and I are working on creating a PDF that will explain the methodologies of it’s boot/load/run process.
As well as releasing the source code on GitHub. More information can be found here.

Please visit our forums for questions.

P-Warrior

This is an example of a simple P-warrior. A program that stores values in P-Space, that determines which strategy it will use.

The execution starts at res. Where the value -1 is loaded into the B-field. Execution continues to label ‘str’. The A-field of _STR is #0, and str1 is 5 addresses forward. Therefore the line for ‘str’ is ldp.a 0, 5. 0 in the P-Space is equal to -1, therefore ldp.a changes str1’s A-Field to -1.

Execution then continues to the if condition sne.ab #0 , res
This checks to see if both A and B fields are equivalent, if they are, execute the next instruction. If not, skip. Since res is equal to -1, they are not equal. Skipping the ‘lost’ label.

mod.a #2, str1
Does the operation -1 % 2 = 1
Making str1’s A-Field equal to 1

stp.ab str1, _STR stores the value of 1 into the 0 space in the P-Space.
Since str1’s A-Field is equal to 1. And _STR is 1, which points to str1. And since str1’s B-Field is equal to 2 (imp is two addresses forward), this stores 1 into the 2 P-field.

Now execution continues to the str1 label.
jmp @1 , 1
The @1 signifies that jmp’s B-field now points to dat 0, stream ‘s B-field. Which is equal to 2.
So str1 becomes:

jmp 1+(2) , 1

Execution jumps to the stream label. And since djn.f’s A-field is a direct/immediate value, it will continuously jump to itself.

Goes 11 addresses behind. Decrement the B value of that address, and then jump from the B value of that address.

assembly hello worlds [intel32]

There are numerous ways to write a hello world program in every programming language. Here are 6 written in 32b assembly using nasm

The top 2 are the std ways of writing this, all the rest are for schittz&gigglz

1-std
1.5-std (NASM style)
2-std using functions
3-writing 1 byte at a time with a forloop
4-pushing 1B, padded so it’s 4B aligned, onto stack, and then writing 1B at a time
5-null-terminated: write until 0x0 encountered
6-pushing string onto stack, and then writing from it

;Guandi97
;std method, the "correct" way to do this

section .text
global _main
_main:
	push 	len
	push	sdr
	push	0x1
	sub	esp,		0x4
	mov	eax,		0x4
	int	0x80
	add	esp,		0x10

	push	0x1
	sub	esp,		0x4		;always 8-byte aligned on intel32
	mov	eax,		0x1
	int	0x80
section .data
sdr	db	"noobie plz",0xa		;consecutive byte sequence, or char array
len	equ	$-sdr				;this is the same as the sizeof() in C

This is an easier way to output a string to the console.

 

;Guandi97
;function call method, the other "correct" way to do this

section .text
global _main
_main:
	push	dword 	sdr
	push 	dword 	len
	call	_rite
	add	esp,		0x8

	push	0x1
	sub	esp,		0x4		;always 8-byte aligned on intel32
	mov	eax,		0x1
	int	0x80
_rite:	push	ebp
	mov	ebp,	esp
	push	dword 	[ebp+0x8]
	push	dword 	[ebp+0xc]
	push	dword	0x1
	sub	esp,		0x4
	mov	eax,		0x4
	int	0x80
	add	esp,		0x10
	pop	ebp
	ret
section .data
sdr	db	"Lunar Republic",0xa
len	equ	$-sdr
;Guandi97
;using a forloop 

;calculate esi,edi
;push args onto stack
;write 1B at a time, and update pointer

section .text
global _main
_main:
	push	ebp
	mov	ebp,		esp	;00
	mov	esi,		sdr
	mov	edi,		esi
	add	edi,		len

	push	dword	0x1		;04
	push	dword 	0x0		;08
	push	dword	0x1		;12
	sub	esp,		0x4	;16

wloops	cmp	esi,		edi
	jge	wloope
	mov	[ebp-0x8],	esi
	mov	eax,		0x4
	int 	0x80
	add	esi,		0x1
	jmp	wloops

wloope	add	esp,		0x10
	push	dword	0x1
	sub	esp,		0x4
	mov	eax,		0x1
	int	0x80
section .data
sdr	db	'twilicorn OP',0xa
len	equ	$-sdr
;Guandi97
;push method

;calculate len 
;push all onto stack
;write 1B at a time

section .text
global _main
_main:
	mov	esi,		sdr
	mov	edi,		esi
	add	esi,		len
ploops	cmp	esi,		edi		;push onto stack
	jl	ploope
	mov	edx,		0x0
	mov	dl,		byte [esi]
	push	edx
	sub	esi,		0x1
	jmp	ploops
ploope	mov	ecx,		0x0
wloops	cmp	ecx,		len		
	jge	wloope
	push	dword 	0x1			;-04
	mov	esi,	esp
	add	esi,	0x4
	push	dword 	esi			;-08			
	push	dword 	0x1			;-12
	sub	esp,		0x4		;-16
	mov	eax,		0x4
	int	0x80
	add	esp,		0x14
	add	ecx,		0x1
	jmp	wloops
wloope	push	dword 	0x1
	sub	esp,		0x4
	mov	eax,		0x1
	int	0x80
section .data
sdr	db	'engieUNion!',0xa
len	equ	$-sdr
;Guandi97
;null terminated while loop

;set edi,esi
;check against 0x0
;write 1B at a time

section .text
global _main
_main:
	push	ebp
	mov	ebp,		esp
	mov	esi,		sdr
	push	dword 	0x1			;04
	push	dword	0x0
	push	dword	0x1
	sub	esp,		0x4
	mov	edi,		ebp
	sub	edi,		0x8
cloops	cmp	byte [esi],	0x0
	je	cloope
	mov	[edi],		esi
	mov	eax,		0x4
	int	0x80
	add	esi,		0x1
	jmp	cloops
cloope	mov	[esp],		dword 0x1
	sub	esp,		0x4	
	mov	eax,		0x1
	int	0x80
section .data
sdr	db	'PootisSpencer here!',0xa,0x0
;Guandi97
;stack byte array method: this method has almost no application irl

;determine esi,edi
;loop esi
;call _byteSStack
;"flush" ebx to stack
;set args, call write

;_byteSStack (8 bit)
	;store in ebx(buffer), accum in eax,
	;shift and add to bl
;_Bflush
	;determin the number of shifts needed to align the fist byte in with the most significant bit in ebx
	;loop shifts

section .text
global _main
_main:
	push	ebp
	mov	ebp,		esp

	mov	edi,		sdr
	mov	esi,		edi
	add	esi,		len
	mov	ebx,		0x0
aloop1s	cmp	esi,		edi
	jle	aloop1e
	call	_byteSStack
	cmp	eax,		0x4		;if eax is full, flush immediately
	jge	bsPush
	jmp	aloop1s
bsPush	push	dword	ebx
	mov	ebx,		0x0
	mov	eax,		0x0
	jmp	aloop1s

aloop1e	cmp	eax,		0x0
	jne	flush
	jmp	end
flush	call	_Bflush				;need to flush manually
	push	dword	ebx
end	push	len		
	mov	edx,		esp
	add	edx,		0x4
	add	edx,		eax
	push	dword 	edx
	push	0x1
	sub	esp,		0x4
	mov	eax,		0x4		;since last 2 args on stack are the same needed for sys_exit(1), interrupt
	int	0x80				;demonstration only, this is bad practice,
	mov	eax,		0x1		;it will confuse both future you, and everybody else who views your code
	int	0x80

_byteSStack:
	sub	esi,		0x1
	shl	ebx,		8		;shift 8b to left
	mov	bl,		byte [esi]
	add	eax,		0x1
	ret
_Bflush:
	mov	edx,		0x4
	sub	edx,		eax
	mov	eax,		edx
	mov	ecx,		0x0
floops	cmp	ecx,		eax		;shift until aligned
	jge	floope
	shl	ebx,		0x8		;shift 8b to left
	add	ecx,		0x1
	jmp	floops
floope	ret
section .data
sdr	db	"AnonyMOOOOOOOOOOooooooooooose",0xa,
len	equ	$-sdr

Minecraft ALU

This is a simple ALU that I made in Minecraft. It has basic functions such as XOR, OR, Adding and Subtracting.
It is not the most efficient, compact or powerful design. There are a lot of designs out there that are ‘better’.

bit Field manipulation [C]

a program demonstrating the different ways to manipulate bits
xor-^
or-|
and-&

some common library functions have been rewritten in an attempt to avoid the standard libraries as much as possible. (for educational purposes)

read(),write() are unix system calls writing to file descriptors
the standard file descriptors open by default are:
0-stdin
1-stdout
2-stderr

the different modes:
m0-use xor
m1-use |,&
m2-assign a number to the 8 bit wide bit field, entering 256 will cause it to overflow, displaying all zeros

#include <stdlib.h>
#include <unistd.h>

void bon(size_t,char*);
void boff(size_t,char*);
void btog(size_t,char*);
void bprint(char*);
int bchek(size_t,char*);
int charLen(char*);
int charInt(char*);
int memcompare(char*,char*,size_t);

int main()
{
	char *buff=(char*)malloc(10); //80 bits
	char *dump=(char*)malloc(100); //800 bits
	char *bfld=calloc(1,1);
	int i;
	int j=0;

	#define INSTR1 "enter: [0-7],print,quit,m[0-2]\nm0:xor\tm1:or/and\tm2:assign #\n"
	write(1,INSTR1,sizeof(INSTR1));

	while(1)
	{
		if(read(0,buff,10)==10) 
		{
			if(*(buff+9)!=0xa) while(100==read(0,dump,100));
			else *(buff+9)=0x0;
		}

		if(memcompare("quit\n",buff,5)==0) exit(0);
		else if(memcompare("print\n",buff,6)==0)
		{
			bprint(bfld);
			continue;
		}
		else if(*buff=='m' && *(buff+1)>47 && *(buff+1)<51)
		{
			if(*(buff!=0xa)
			{
				#define INSTR2 "invalid input\n"
				write(1,INSTR2,sizeof(INSTR2));
				continue;
			}
			j=charInt((buff+1));
			continue;
		}
		else
		{
			if(j==0)
			{
				if(!(*buff>47 && *buff<56) || *(buff+1)!=0xa)
				{
					write(1,INSTR2,sizeof(INSTR2));
					continue;
				}
			}
			else if(j==1)
			{
				if(!(*buff>47 && *buff<56) || *(buff+1)!=0xa)
				{
					write(1,INSTR2,sizeof(INSTR2));
					continue;
				}
			}
		}

		i=charInt(buff);

		if(j==0) btog(i,bfld);
		else if(j==1)
		{
			if(bchek(i,bfld)==0) bon(i,bfld);
			else boff(i,bfld);
		}
		else *bfld=i;

		bprint(bfld);
	}

	return 0;

}

void bon(size_t i,char *bfld)
{
	*bfld|=(1<<i);
}
void boff(size_t i,char *bfld)
{
	*bfld&=~(1<<i);
}
void btog(size_t i,char *bfld)
{
	*bfld^=(1<<i);
}
int bchek(size_t i,char *bfld)
{
	if((*bfld&(1<<i))==0) return 0;
	else return 1;
}
void bprint(char *bfld)
{
	char i,b[9]={0};
	for(i=0;i<8;i++)
	{
		if(bchek(7-i,bfld)==0) b[i]=48;
		else b[i]=49;
	}
	b[++i]=0xa;
	write(1,&b,10);
}

int charLen(char *c)
{
	int i=0;
	while(*(c+i)!=0xa && *(c+i)!=0x0) 
	{
		i++;
	}
	return i;
}
int charInt(char *c)
{
	int i,j,k=0,l=1;

	for(j=charLen(c)-1;j!=-1;j--)
	{
		switch(*(c+j))
		{
			case '0': i=0; break;
			case '1': i=1; break;
			case '2': i=2; break;
			case '3': i=3; break;
			case '4': i=4; break;
			case '5': i=5; break;
			case '6': i=6; break;
			case '7': i=7; break;
			case '8': i=8; break;
			case '9': i=9; break;
		}
		k+=i*l;
		l*=10;
	}
	return k;
}
int memcompare(char *str1,char *str2,size_t j)
{
	int i;
	for(i=0;i<j;i++)
	{
		if(*(str1+i)!=*(str2+i)) return i+1;
	}
	return 0;
}

Rotating a Matrix [Java][C++]

This is a simple way of rotating a matrix clockwise or counter-clockwise. I will use Java to demonstrate. First, notice the pattern when you are rotating a matrix’ values clockwise:

Original 3 x 3 matrix:

[1][2][3]
[4][5][6]
[7][8][9]

Rotating last row:
[2][0] => [0][0]
[2][1] => [1][0]
[2][2] => [2][0]

Rotating middle row:
[1][0] => [0][1]
[1][1] => [1][1]
[1][2] => [2][1]

Rotating last row:
[0][0] => [0][2]
[0][1] => [1][2]
[0][2] => [2][2]

Note that you will need two loops for each row rotation.
One for incrementing through the row of the first matrix, and the second for incrementing through the rows and columns of the new matrix. In this method, we use a counter (z) for incrementing through each row of the new matrix while keeping the column the same.

Code:

 

Get dat cat to Purr()

I really want that Cat to Purr()!

//Justin
#include 
using namespace std;

class Mammal
{
public:
	virtual void Speak() const {cout << "Mammal Talk!"; }

};

class Cat : public Mammal
{
public:
	void Speak() const { cout << "Meow!"; }
	void Purr() const { cout << "RRRRRRRRRRrr"; }
};

class Dog : public Mammal
{
public:
	void Speak() const { cout << "Wolf!"; }
};

int main()
{

	Mammal * pMammal;

	pMammal = new Cat;

	Cat * lol = dynamic_cast<Cat*> (pMammal);

	lol->Purr();
        cout << "The Game." << endl;

	cin.get();
	return 0;
}

Cat is a derived class from Mammal and overrides the Speak() function. Since all Mammals know how to Speak(), this is polymorphic and makes sense in our code. What if I want a Cat object to know how to code, but not another derived Mammal class like Dog? You can percolate Purr() up into Mammal but that’s bad practice, since it doesn’t apply to Dog.

What you can do is use dynamic_cast to safely cast the pointer as a pointer to a Cat object. Dynamic_cast provides a run-time safety check to ensure that it is indeed a pointing to a valid Cat object.

Cat * paw = dynamic_cast<Cat* > (pMammal)

paw->Purr();

Hax!!

Why would you want to do this? I don’t know. It’s not very polymorphic.