DakienDX
June 1st, 2001, 07:05
(First part, since my message is longer than 4098 bytes)
Hello everybody !
First of all, I don't want to talk about who is able to program good programs and who's not.
I haven't seen much of Harlequin so I can't judge him, this error could have happened to erverybody.
To come to the main subject of this post, you know that Harlequin tried to find a way to protect programs from being terminated by trojan horses. They use the API-function TerminateProcess() to terminate a process. This function doesn't send any warning to the application being terminated and just kills it.
Harlequin tried to fix this by injecting some code into Kernel32.dll to call an external library which asks if you wish to allow the program which tries to terminate an other one to do it.
He called GetCurrentProcessId to get the PID of the process calling TerminateProcess() and the creates a snapshop of all processes and compares the PID with them to get the path of the calling program.
This is a good idea and well implemented.
But... This isn't made at first.
At first he tries to get the path of the application to be terminated.
He does it the following way:
Term proc
Start:
mov eax,dword ptr[esp+4] ;get the PID from the stack
mov PID,eax ;and save it
and then compares the "PID" to the processes in the snapshot. But the "PID" isn't the ProcessID, it's the HANDLE of the process to be terminated, so you can't find any matches in the snapshot, because you would compare if the PID and a HANDLE are the same. If it doesn't find any match, it returns with EAX = 0. This forces the Kernel32.dll patched code to exit without terminating. This does mean two things: 1.) you can't terminate any process any longer, 2.) since the return to the calling process is made via a "ret" and not via a "ret 8" (since TerminateProcess() has two parameters on the stack), the calling process has the stack 8 bytes to low and will probably crash.
I don't know if there is a way to get the PID of a process if you have only it's HANDLE.
(Continued in the next part)
Hello everybody !
First of all, I don't want to talk about who is able to program good programs and who's not.
I haven't seen much of Harlequin so I can't judge him, this error could have happened to erverybody.
To come to the main subject of this post, you know that Harlequin tried to find a way to protect programs from being terminated by trojan horses. They use the API-function TerminateProcess() to terminate a process. This function doesn't send any warning to the application being terminated and just kills it.
Harlequin tried to fix this by injecting some code into Kernel32.dll to call an external library which asks if you wish to allow the program which tries to terminate an other one to do it.
He called GetCurrentProcessId to get the PID of the process calling TerminateProcess() and the creates a snapshop of all processes and compares the PID with them to get the path of the calling program.
This is a good idea and well implemented.
But... This isn't made at first.
At first he tries to get the path of the application to be terminated.
He does it the following way:
Term proc
Start:
mov eax,dword ptr[esp+4] ;get the PID from the stack
mov PID,eax ;and save it
and then compares the "PID" to the processes in the snapshot. But the "PID" isn't the ProcessID, it's the HANDLE of the process to be terminated, so you can't find any matches in the snapshot, because you would compare if the PID and a HANDLE are the same. If it doesn't find any match, it returns with EAX = 0. This forces the Kernel32.dll patched code to exit without terminating. This does mean two things: 1.) you can't terminate any process any longer, 2.) since the return to the calling process is made via a "ret" and not via a "ret 8" (since TerminateProcess() has two parameters on the stack), the calling process has the stack 8 bytes to low and will probably crash.
I don't know if there is a way to get the PID of a process if you have only it's HANDLE.
(Continued in the next part)