Code, to achieve a function, directly Ctrl+C and Ctrl+V can solve the problem. But it says driver can be added?
Loading the kernel is another matter, and whether it can be stored on someone else's hard disk is another matter.
Because many antivirus software (especially non-technical ones like 360) directly delete files with the suffix sys,
I didn't even get a chance to call NtLoadDriver. For general software, give a statement to explain the solution.
Forget the solution. But for malicious programs, you can't give a statement. So many malware authors have found another way.
Do bad things with digital signature drivers written by big companies.
Some people say, how can the drivers made by big companies be used to do bad things? Actually, it's easy to understand.
Many security or system optimization softwares, even those unrelated to the system (such as Thunder) have their own drivers.
These drives are all universal. Q_lai_a_qu netizen said in his blog: "ComputerZ.sys…… ...................................................................................................................................................
The reverse is the driver of Master Lu, and it is found that this driver is fully functional and has not been verified by the caller! Can read and write Msr
Register, you can also use in and out instructions to read and write ports, char/short/long data length is complete! "。 this is
Personally, please guess the credibility by yourself. Let's start with a more credible example: there was a virus that used 360.
Antirk.dll's antivirus software for deleting files (please Google "360 antirk.dll" yourself, and you will be pleasantly surprised.
AntiRK.dll is not a driver, but it is also illegally used). The virus that destroys antivirus software is pediatrics.
In fact, some drivers can also destroy hardware! Recently, I was tossing hardware in my notebook, and the netizens on the "Friendship Association" pushed it for me.
Recommend several softwares: SetFSB, ThrottleStop, NvFlash, WinFlash. They are modifying the external frequency and setting of CPU.
Software for setting CPU frequency doubling (CPU voltage is adjustable), reading and writing graphics BIOS and reading and writing motherboard BIOS. Summarize their characteristics in one sentence,
That is, they all support NT x86/x64, and the drivers all have formal digital signatures (especially the last two, which have the digital signatures of NVIDIA and Asus respectively).
Most importantly, their driver has no fancy cover, and the caller has not been verified.
If you use these drivers and a little reverse knowledge, you can make a destructive virus (the following is taken from my purple water
Crystal programming forum post):
1.SetFSB can adjust the external frequency of the processor. If the external frequency is directly adjusted to 600MHz, the computer will instantly go black, which may be
Will damage the CPU or motherboard;
2.ThrottleStop can adjust the frequency doubling of the CPU (if the CPU does not lock the frequency doubling), if the frequency doubling is directly adjusted to 3 1,
The computer will go black in an instant, which may damage the CPU or motherboard; ThrottleStop can also adjust the core voltage of CPU, if
Adjusting the core voltage of CPU to 3V can directly burn CPU or even motherboard;
3.NvFlash, WinFlash and other software can directly read and write BIOS (graphics BIOS and motherboard BIOS), we can put
BIOS writes all zeros;
4. If you are a virus, first write bad graphics BIOS and motherboard BIOS, and then burn the graphics card and CPU by adjusting the voltage.
(May be damaged together with the motherboard);
solution
It can be seen that it is very harmful not to verify the caller. I was recently appointed by the college as
Software that requires a driver (the driver will be digitally signed). In order to prevent the above tragedy, I decided to formally write.
Before driving, solve how to prevent your driver from being used maliciously. I asked this question in amethyst programming forum before.
Netizens have various answers to this question, but they can be roughly divided into three categories: the first category is information verification, such as applications.
Send a message to the driver in order to verify that it is "one of our own"; The second category is shell protection, such as adding to drivers and applications.
On the extremely hard shell, the communication part is encrypted by VMP (similar to the practice of XueTr); Others have proposed mixed applications, synthesis
The combination of the first category and the second category.
All three ideas seem good, but I don't think they are right. The first type: others just need to reverse all the drivers.
Yes; Second: although VMP protection and protection shell make cracking difficult, it does not make cracking impossible. and
I don't like that VMP and the protective shell will reduce the efficiency of program execution. Worst of all, antivirus software has added a shell (even)
Even projects including UPX and VMP are reported to be poisoned, which is not worth the loss. So I came up with a third idea: check the caller's
Features. If yes, the function statement is executed, otherwise it is not executed. How to check the caller's signature? A lot of people want to
Use CRC32 or MD5. It's not that I can't use them, but I have my own ideas. My idea comes from
A set of verification algorithm is designed, and its rules are as follows:
1. Get the caller's electronic flow.
2. Get the caller's file path through the caller's EPROCESS.
3. Get all the contents of the caller file and put it into the byte array buffer.
4. Add and subtract all the elements in the buff (fb 1+fb2-fb3 ...) in order to get y 1.
5. XOR all the elements in the buff (0 XOR fb 1 XOR fb2 XOR fb3 ...) in turn to obtain y2.
Compare y 1 and y2 with the calculated values. If they are all the same, execute the function code; If they are different, they are different.
Executive function code
Use PsGetCurrentProcess () to get the caller's EPROCESS directly and get the caller's file path.
The path is troublesome. You can use the code I bought from the master before (it has been encapsulated into a function for easy calling):
//Get the full path of the process according to e process.
VOID getfullpathbyprocess(ULONG e process,PCHAR ProcessImageName)
{
ULONG object;
PFILE _ OBJECT FileObject
UNICODE_STRING file path;
UNICODE _ STRING DosName
String rearrangement;
FileObject = NULL
File path. Buffer = NULL
File path. Length = 0;
* process imagename = 0;
//e process-& gt; section object(offset _ section object)
if(MmIsAddressValid((PULONG)(e process+offset _ section object)))
{
object =(*(PULONG)(e process+offset _ section object));
//KD print(("[GetProcessFileName]section object:0x % x \ n ",object));
if(MmIsAddressValid((PULONG)((ULONG)object+0x 0 14)))
{
object = *(PULONG)((ULONG)object+0x 0 14);
//KD print(("[GetProcessFileName]Segment:0x % x \ n ",object));
if(MmIsAddressValid((PULONG)((ULONG)object+0x 0)))
{
object = *(PULONG)((ULONG _ PTR)object+0x 0);
//KD print(("[GetProcessFileName]
ControlAera :0x%x\n ",object));
if(MmIsAddressValid((PULONG)((ULONG)object+0x 024)))
{
object = *(PULONG)((ULONG)object+0x 024);
if(NtBuildNumber & gt; = 6000)object =((ULONG)object & amp;
0x fffffff 8);
//KD print(("[GetProcessFileName]
FilePointer :0x%x\n ",object));
}
other
Return;
}
other
Return;
}
other
Return;
}
other
Return;
FileObject=(PFILE_OBJECT) object;
File path. buffer = ExAllocatePool(page pool,0x 200);
File path. MaximumLength = 0x200
//KD print(("[GetProcessFileName]
File pointer: %wZ\n ",& file pointer-> File name));
ObReferenceObjectByPointer((PV oid)file object,0,NULL,kernel mode);
RtlVolumeDeviceToDosName(file object-& gt; Device object. dos name);
RtlCopyUnicodeString(& amp; File path. dos name);
rtlapendunicodestringtostring(& amp; File path. file object-& gt; File name);
ObDereferenceObject(file object);
rtlunicodestringtansigning(& amp; Distribution and distribution. FilePath,TRUE);
If (registering. Length & gt= 2 16)
{
memcpy(ProcessImageName,AnsiString。 Buffer, 0x100u);
*(process imagename+2 15)= 0;
}
other
{
memcpy(ProcessImageName,AnsiString。 Buffer and distribute. Length);
ProcessImageName[AnsiString。 Length] = 0;
}
rtlfreeansigning(& amp; ansi ssing);
ExFreePool(DosName。 Buffer);
ExFreePool (file path. Buffer);
}
The above code requires three hard codes, namely, NtBuildNumber (system version number) and EPROCESS.
Offset of SectionObject item and UniqueProcessId item. The operating system I tested is Windows 2003. therefore
I define it in the code as follows:
# define offset _ section object 0x 124
# define offset _ UniqueProcessId 0x 94
ULONG NtBuildNumber = 3790
Check the signature after obtaining the process path. Because the process has been made clear, the code is given directly:
VOID CalcChar(puni code _ STRING logFileUnicodeString,LONG *XorChar,LONG
*AnSChar)
{
OBJECT_ATTRIBUTES object properties;
IO _ STATUS _ BLOCK iostatus
Handling hfile
NTSTATUS ntStatus
File _ standard _ information;
Puchal Pfeiffer;
ULONG i=0,y 1=0,y2 = 0;
//Initialize object properties
InitializeObjectAttributes(& amp; Object properties,
logFileUnicodeString,
OBJ is case-insensitive,//case-sensitive.
Empty,
NULL);
//Create file
ntStatus = ZwCreateFile(& amp; hfile,
GENERIC_READ
& object properties,
& ampiostatus,
Empty,
File _ Properties _ Normal,
File share reading,
FILE_OPEN,//Even if it exists in this file, it is created.
File _ sync _ IO _ non-alarm,
Empty,
0 );
If (! NT_SUCCESS(ntStatus))
{
Dprintf ("file does not exist! \ n ");
Return;
}
//Read the file length
ntStatus = ZwQueryInformationFile(hfile,
& ampiostatus,
& ampfsi,
Sizeof (document standard information),
File standard information);
Dprintf ("The program wants to read %d bytes \n", fsi. endo ffile . quad part);
//Allocate a buffer for the read file
pBuffer =(PUCHAR)ExAllocatePool(paged pool,
(long) fsi. endo ffile . quad part);
//Read the file
ZwReadFile(hfile,NULL,
Empty, empty,
& ampiostatus,
P buffer,
(long) fsi. Four parts,
NULL、NULL);
Dprintf ("The program did read %d bytes \n", iostatus. Information);
//XOR calculation
for(I = 0; Me & ltiostatus. Information; i++)
y 1=y 1^(long)(*(pbuffer+i));
* xor char = y 1;
//addition and subtraction operation
for(I = 0; Me & ltiostatus. Information; i++)
{
If (i%2==0)
y2 = y2+(LONG)(*(p buffer+I));
other
y2 = y2-(LONG)(*(p buffer+I));
}
* AnSChar = y2
//Close the file handle
zw close(hfile);
//Release the buffer
ex free pool(p buffer);
}
It will be called next. We need to write a function VerifyCaller, which has two values.
Solidified in the driver are two characteristic values of the legitimate caller. In order to calculate these two eigenvalues conveniently, I specially wrote one.
Application, the core code is as follows:
Option explicit
Private function ReadFile(ByVal strFileName as a string, optional ByVal
LngStartPos As Long = 1, optional byvallngfilesize as long =-1) as byte ().
Dim FilNum As Long
FilNum = FreeFile
Open strFileName of binary file in #FilNum format.
If lngFileSize =-1, then
ReDim ReadFile(LOF(FilNum)-lngStartPos)
other
ReDim ReadFile(lngFileSize- 1)
If ... it will be over.
Get #FilNum,lngStartPos,ReadFile
Close #FilNum
End function
Private function WriteFile(ByVal strFileName is a string, bytData () is a byte,
Optional byval LNG startpos as long =-1,optional ByVal OverWrite As Boolean =
True)
Go to erx when an error occurs.
Dim FilNum As Long
FilNum = FreeFile
If OverWrite = True and dir (strfilename) <: & gt ""So
Kill strFileName
If ... it will be over.
Open strFileName of binary file in #FilNum format.
If lngStartPos =-1
Put #FilNum, LOF(FilNum)+1, bytData.
other
Will #FilNum, lngStartPos, bytData.
If ... it will be over.
Close #FilNum
erx:
End function
Private subcommand 1_Click ()
Dim buff () is byte, I is Long, Y is Long, ub is Long.
Text 1.text is the file name.
buff = ReadFile(Text 1。 Text, 1,- 1)
ub = UBound(buff)
Calculate XOR character
y = 0
For i = 0 to ub
Y = y XOR buffer (I)
then
Text 2. Text = CLng(y)
Multiple activities
Calculate Add/Subcharacters
y = 0
For i = 0 to ub
If I modulo 2 = 0, then
y = y + CLng(buff(i))
other
y = y - CLng(buff(i))
If ... it will be over.
then
SMS 3. Text = CLng(y)
End joint
Private Sub-Form _Load ()
Me. Icon = LoadPicture(" ")
End joint
The VerifyCaller code in the driver is as follows:
Long Authentication Caller (Invalid)
{
PEPROCESS cur _ ep
char cur _ PP[260];
char * nt _ cur _ pp
ANSI _ STRING asCur _ pp
UNICODE _ STRING usCur _ pp
LONG xorc,ansc
cur _ EP = PsGetCurrentProcess();
getfullpathbyprocess((ULONG)cur _ EP,cur _ PP);
//Add \? Before the file name. \
nt_cur_pp=cs("\\? \\ ",cur _ PP);
DbgPrint("%s ",nt _ cur _ PP);
rtlinitansigning(& amp; asCur_pp,nt _ cur _ PP);
rtlansistringunicodestring(& amp; us cur _ PP & amp; asCur_pp,TRUE);
DbgPrint("%wZ ",& ampus cur _ PP);
Karchar (& ampus cur _ PP & amp; xorc & amp; ansc);
dbg print(" xor char:% LD; AnSChar: %ld ",xorc,ansc);
//This is a pre-calculated feature code of a legal program and must be solidified in the driver!
if(xorc = = 186 & amp; & ampansc== 136 176)
Returns1;
other
Returns 0;
}
Before executing each function of the DispatchIoctl function, call VerifyCaller () to check the caller:
Switch (uIoControlCode)
{
Case IOCTL_VERIFY:
{
dbg print("[my driver]DispatchIoctl-IOCTL _ VERIFY ");
if(VerifyCaller()== 1)
Dbgprint ("[mydriver] {ioctl _ verify} function code is running now!" );
other
Dbgprint ("[mydriver] {ioctl _ verify} You are an illegal caller!" );
Status = Status _ Success;
Break;
}
//omitted below
}
Exploratory test
3. First, the legitimate caller and the illegal caller (patch the legitimate caller casually with eXeScope,
E.g., deleting the version information of the program) and copying the driver to the virtual machine.
4. Load the driver with a legitimate caller and execute it.
5. Load the driver with an illegal caller and execute it.
6. Compare the output of the above two in DbgView.
When the caller is legitimate:
When the caller is illegal:
Write it at the end
After writing this article, I must reiterate that only when the driver carries a formal digital signature can the caller's.
Code is useful. Why do you say that? Because others can't patch the driver with a formal digital signature (once
When the driver is a patch, the signature will be invalid, just like a broken woman, worthless. Although this metaphor is vulgar, it is very
Suitable). Without signature driver, there is no use value. Even if others want to use it, just throw it at the driver.
In IDA, all the code came out.