makehookvc.perl
Perl source for WinSock hook, 300 lines. Raw file
# Generates a replacement wsock32.dll that logs each WinSock call and
# forwards it to the real DLL.
#
# (An earlier version rewrote the address inside each call, pointing
# http://www.roland.co.uk/cgi-bin/ at a copy on another server.)
#
$exports = 'exports.txt';
$dllsource = 'wshookvc';
$dll = 'c:\\\\windows\\\\system\\\\wsock32.dll';
sub main {
#- Generate C code
&code_c();
#- Generate LBC file (Watcom - although Watty's LBC handling doesn't work!)
&code_lbc();
#- Generate DEF file (For good ol' visual C)
&code_def();
}
sub getexports {
local($line);
while(@exports) { pop @exports; }
if(open(EXPORTS, $exports)) {
while($line = <EXPORTS>) {
chop $line;
if($line ne '' && substr($line, 0, 2) ne '//') {
push(@exports, $line);
}
}
close(EXPORTS);
} else {
print "ERROR - Could not open exports file '$exports'";
}
@exports = reverse sort @exports;
}
sub getname {
local($exp) = @_;
local($ord, $name);
($ord, $name) = split(/ /, $exp);
$ord =~ s/([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9])/pack("I", hex($1))/eg;
return $name;
}
sub getordinal {
local($exp) = @_;
local($ord, $name);
($ord, $name) = split(/ /, $exp);
$ord =~ s/([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9])/hex($1)/eg;
return $ord+1;
}
sub code_lbc {
local($exp);
&getexports();
open(LBCFILE, '>'.$dllsource.'.lbc');
print LBCFILE "OPTION MODNAME=wsock32\n";
print LBCFILE "OPTION DESCRIPTION 'LKS WinSock Hook DLL'\n";
print LBCFILE "EXPORT\n";
print LBCFILE "DllMain='_DllMain\@12',\n";
print LBCFILE "DllEntryPoint='_DllMain\@12',\n";
while(@exports) {
$exp = pop(@exports);
print LBCFILE &getname($exp).'.'.&getordinal($exp)."='_my_".&getname($exp)."\@0'";
if(@exports) { print LBCFILE ","; }
print LBCFILE "\n";
}
print LBCFILE "\n";
print LBCFILE "\n";
close(LBCFILE);
}
sub code_def {
local($exp);
&getexports();
open(DEFFILE, '>'.$dllsource.'.def');
print DEFFILE "EXPORTS\n";
while(@exports) {
$exp = pop(@exports);
print DEFFILE &getname($exp).' @'.&getordinal($exp)."\n";
}
print DEFFILE "\n";
print DEFFILE "\n";
close(DEFFILE);
}
sub code_c {
local($exp);
open(CFILE, '>'.$dllsource.'.c');
print CFILE <<EOR;
#include <stdio.h>
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//#include <winsock.h>
//---- APPLICATION PARAMETERS ------------------------------------------------//
#define SZAPPNAME "LKS WinSock Hook DLL"
#define SZDESCRIPTION "Logs WinSock calls by hooking WinSock DLL"
#define SZVERSION "Version 4.0"
#define SZRCOMPANYNAME "LKS"
#define SZRDESCRIPTION "LKS WinSock Hook DLL"
#define SZRVERSION "v0.01"
#define SZRAPPNAME "WS_HOOK"
#define SZRCOPYRIGHT "<c> LKS 1999"
#define SZRTRADEMARK "-"
#define SZRPRODNAME "-"
#define SZRPRODVER "-"
//---- IMPORTED FUNCTIONS ----------------------------------------------------//
EOR
&getexports();
while(@exports) {
$exp = pop @exports;
print CFILE "static int (WINAPI FAR *real_".&getname($exp).")(); // ".&getordinal($exp)."\n";
}
print CFILE <<EOR;
//---- FUNCTION PROTOS -------------------------------------------------------//
//---- DEBUG FUNCTIONS -------------------------------------------------------//
/*
void abc(char * p) {
FILE *fp=fopen("c:\\z.txt","a+");
fprintf(fp,"%s\n",p);
fclose(fp);
}
char aa[1000];
*/
//#define abc(a)
void abc(char * p) {
HDC dc = GetDC(NULL);
int i;
for(i=0; p[i]; i++);
TextOut(dc, 0, 1000, p, i);
ReleaseDC(NULL, dc);
}
//---- IMPORT FUNCTION -------------------------------------------------------//
#define SHIM_GETPROCADDRESS(f) real_##f = GetProcAddress(ws_inst, "" #f)
char RealImport_msg[256];
int RealImport_errors = 0;
FARPROC RealImport(HINSTANCE inst, char *name) {
FARPROC f;
f = GetProcAddress(inst, name);
if(!f) {
RealImport_errors ++;
sprintf(RealImport_msg, "Error importing function '%s'", name);
MessageBox(0, RealImport_msg, "LKS $dll hook", IDOK);
}
return f;
}
//---- DLL ENTRY POINT -------------------------------------------------------//
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) {
if(reason == DLL_PROCESS_ATTACH) {
HINSTANCE ws_inst = LoadLibrary("$dll");
abc("DLL Started for a new process");
if(!ws_inst) {
abc("ERROR: Could not load DLL '$dll'");
return FALSE;
}
abc("DLL '$dll' loaded ok");
EOR
&getexports();
while(@exports) {
$exp = pop(@exports);
print CFILE " real_".&getname($exp)." = RealImport(ws_inst, \"".&getname($exp)."\"); // ".&getordinal($exp)."\n";
}
print CFILE <<EOR;
if(RealImport_errors == 0) {
// All functions imported sucessfully!
abc("All functions imported sucessfully!");
} else {
abc("ERROR - Could not import function(s)!");
return FALSE;
}
}
return TRUE;
}
//---- MY REPLACEMENT FUNCTIONS ----------------------------------------------//
EOR
&getexports();
while(@exports) {
$exp = pop(@exports);
print CFILE "__declspec(naked) __declspec(dllexport) WINAPI FAR ".&getname($exp)." () {\n";
print CFILE " abc(\"".&getname($exp)."\");\n";
print CFILE " _asm jmp[real_".&getname($exp)."];\n";
print CFILE "}\n\n";
}
print CFILE <<EOR;
//---- END OF CODE -----------------------------------------------------------//
//---- Code generated by LKS Makehook.perl :)
EOR
close(CFILE);
}
{ main(); }