mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Record times taken within stub functions
Reporting not done yet. Call logging broken (for now).
This commit is contained in:
parent
fd4d78575d
commit
7e6280b560
26
Makefile
26
Makefile
@ -1,5 +1,5 @@
|
||||
# IPXWrapper - Makefile
|
||||
# Copyright (C) 2011-2017 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
# Copyright (C) 2011-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as published by
|
||||
@ -86,62 +86,62 @@ dist: all
|
||||
|
||||
IPXWRAPPER_OBJS := src/ipxwrapper.o src/winsock.o src/ipxwrapper_stubs.o src/log.o src/common.o \
|
||||
src/interface.o src/router.o src/ipxwrapper.def src/addrcache.o src/config.o src/addr.o \
|
||||
src/firewall.o src/wpcap_stubs.o src/ethernet.o
|
||||
src/firewall.o src/ethernet.o src/funcprof.o
|
||||
|
||||
ipxwrapper.dll: $(IPXWRAPPER_OBJS)
|
||||
echo 'const char *version_string = "$(VERSION)", *compile_time = "'`date`'";' | $(CC) -c -x c -o version.o -
|
||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ version.o -liphlpapi -lversion -lole32 -loleaut32
|
||||
|
||||
src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt
|
||||
perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s 0
|
||||
perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s
|
||||
|
||||
#
|
||||
# WSOCK32.DLL
|
||||
#
|
||||
|
||||
wsock32.dll: src/stubdll.o src/wsock32_stubs.o src/log.o src/common.o src/config.o src/addr.o src/wsock32.def
|
||||
wsock32.dll: src/stubdll.o src/wsock32_stubs.o src/log.o src/common.o src/config.o src/addr.o src/funcprof.o src/wsock32.def
|
||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^
|
||||
|
||||
src/wsock32_stubs.s: src/wsock32_stubs.txt
|
||||
perl mkstubs.pl src/wsock32_stubs.txt src/wsock32_stubs.s 1
|
||||
perl mkstubs.pl src/wsock32_stubs.txt src/wsock32_stubs.s
|
||||
|
||||
#
|
||||
# MSWSOCK.DLL
|
||||
#
|
||||
|
||||
mswsock.dll: src/stubdll.o src/mswsock_stubs.o src/log.o src/common.o src/config.o src/addr.o src/mswsock.def
|
||||
mswsock.dll: src/stubdll.o src/mswsock_stubs.o src/log.o src/common.o src/config.o src/addr.o src/funcprof.o src/mswsock.def
|
||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^
|
||||
|
||||
src/mswsock_stubs.s: src/mswsock_stubs.txt
|
||||
perl mkstubs.pl src/mswsock_stubs.txt src/mswsock_stubs.s 2
|
||||
perl mkstubs.pl src/mswsock_stubs.txt src/mswsock_stubs.s
|
||||
|
||||
#
|
||||
# DPWSOCKX.DLL
|
||||
#
|
||||
|
||||
dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o src/config.o src/addr.o src/dpwsockx.def
|
||||
dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o src/config.o src/addr.o src/funcprof.o src/dpwsockx.def
|
||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ -lwsock32
|
||||
|
||||
src/dpwsockx_stubs.s: src/dpwsockx_stubs.txt
|
||||
perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s 3
|
||||
perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s
|
||||
|
||||
#
|
||||
# IPXCONFIG.EXE
|
||||
#
|
||||
|
||||
IPXCONFIG_OBJS := src/ipxconfig.o icons/ipxconfig.o src/addr.o src/interface.o src/common.o \
|
||||
src/config.o src/wpcap_stubs.o
|
||||
src/config.o src/ipxconfig_stubs.o src/funcprof.o
|
||||
|
||||
ipxconfig.exe: $(IPXCONFIG_OBJS)
|
||||
$(CXX) $(CXXFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -static-libstdc++ -mwindows -o $@ $^ -liphlpapi -lcomctl32 -lws2_32
|
||||
|
||||
src/ipxconfig_stubs.s: src/ipxwrapper_stubs.txt
|
||||
perl mkstubs.pl src/ipxconfig_stubs.txt src/ipxconfig_stubs.s
|
||||
|
||||
#
|
||||
# SHARED TARGETS
|
||||
#
|
||||
|
||||
src/wpcap_stubs.s: src/wpcap_stubs.txt
|
||||
perl mkstubs.pl src/wpcap_stubs.txt src/wpcap_stubs.s 5
|
||||
|
||||
icons/%.o: icons/%.rc icons/%.ico
|
||||
$(WINDRES) $< -O coff -o $@
|
||||
|
||||
|
250
mkstubs.pl
250
mkstubs.pl
@ -1,5 +1,5 @@
|
||||
# IPXWrapper - Generate assembly stub functions
|
||||
# Copyright (C) 2008-2011 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
# Copyright (C) 2008-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as published by
|
||||
@ -17,75 +17,239 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
if(@ARGV != 3) {
|
||||
print STDERR "Usage: mkdll.pl <function list> <output file> <dll number>\n";
|
||||
if(@ARGV != 2) {
|
||||
print STDERR "Usage: mkdll.pl <stub definitions file> <asm output file>\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
# Must be kept in sync with dll_names in common.c!
|
||||
my %DLL_INDICES = (
|
||||
"ipxwrapper.dll" => 0,
|
||||
"wsock32.dll" => 1,
|
||||
"mswsock.dll" => 2,
|
||||
"dpwsockx.dll" => 3,
|
||||
"ws2_32.dll" => 4,
|
||||
"wpcap.dll" => 5,
|
||||
);
|
||||
|
||||
my $stub_file = $ARGV[0];
|
||||
my $asm_file = $ARGV[1];
|
||||
my $dllnum = $ARGV[2];
|
||||
my $do_logging = ($dllnum != 0);
|
||||
|
||||
open(STUBS, "<$stub_file") or die("Cannot open $stub_file: $!");
|
||||
open(CODE, ">$asm_file") or die("Cannot open $asm_file: $!");
|
||||
|
||||
my @stubs = ();
|
||||
my @stubs_dll = ();
|
||||
|
||||
foreach my $line(<STUBS>) {
|
||||
# Skip over header
|
||||
(scalar <STUBS>);
|
||||
(scalar <STUBS>);
|
||||
|
||||
# Read in stub definitions
|
||||
foreach my $line(<STUBS>)
|
||||
{
|
||||
$line =~ s/[\r\n]//g;
|
||||
|
||||
if($line ne "") {
|
||||
my ($func, $dn) = split(/:/, $line);
|
||||
$dn = $dllnum if(!defined($dn));
|
||||
my ($name, $target_dll, $target_func, $params) = split(/\s+/, $line);
|
||||
|
||||
my $sym = $func;
|
||||
$sym =~ s/^r_//;
|
||||
my $target_dll_index = $DLL_INDICES{$target_dll}
|
||||
// die "Unknown DLL: $target_dll\n";
|
||||
|
||||
push(@stubs, {"name" => $func, "sym" => $sym, "dllnum" => $dn});
|
||||
push(@stubs, {
|
||||
name => $name,
|
||||
target_dll => $target_dll,
|
||||
target_dll_index => $target_dll_index,
|
||||
target_func => $target_func,
|
||||
params => $params,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
print CODE "section .rdata:\n";
|
||||
print CODE <<"END";
|
||||
extern _QueryPerformanceCounter\@4
|
||||
|
||||
foreach my $func(@stubs) {
|
||||
print CODE "\t".$func->{"name"}."_sym:\tdb\t'".$func->{"sym"}."', 0\n";
|
||||
extern _find_sym
|
||||
extern _log_call
|
||||
extern _fprof_record_timed
|
||||
extern _fprof_record_untimed
|
||||
|
||||
struc FuncStats
|
||||
.func_name: resd 1
|
||||
.min_time: resd 1
|
||||
.max_time: resd 1
|
||||
.total_time: resd 1
|
||||
.n_calls: resd 1
|
||||
|
||||
.cs: resb 24
|
||||
endstruc
|
||||
END
|
||||
|
||||
print CODE <<"END";
|
||||
section .rdata
|
||||
END
|
||||
|
||||
foreach my $func(@stubs)
|
||||
{
|
||||
print CODE <<"END";
|
||||
$func->{name}_name: db '$func->{name}', 0
|
||||
$func->{name}_target_func: db '$func->{target_func}', 0
|
||||
END
|
||||
}
|
||||
|
||||
print CODE "\nsection .data\n";
|
||||
print CODE <<"END";
|
||||
section .data
|
||||
END
|
||||
|
||||
foreach my $func(@stubs) {
|
||||
print CODE "\t".$func->{"name"}."_addr:\tdd\t0\n";
|
||||
foreach my $func(@stubs)
|
||||
{
|
||||
print CODE <<"END";
|
||||
$func->{name}_addr: dd 0
|
||||
END
|
||||
}
|
||||
|
||||
print CODE "\nsection .text\n";
|
||||
print CODE "\textern\t_find_sym\n";
|
||||
print CODE "\textern\t_log_call\n" if($do_logging);
|
||||
print CODE <<"END";
|
||||
global _stub_fstats
|
||||
_stub_fstats:
|
||||
END
|
||||
|
||||
foreach my $func(@stubs) {
|
||||
my $f_name = $func->{"name"};
|
||||
|
||||
print CODE "\nglobal\t_$f_name\n";
|
||||
print CODE "_$f_name:\n";
|
||||
|
||||
if($do_logging) {
|
||||
print CODE "\tpush\tdword ".$func->{"dllnum"}."\n";
|
||||
print CODE "\tpush\t$f_name\_sym\n";
|
||||
print CODE "\tpush\tdword $dllnum\n";
|
||||
print CODE "\tcall\t_log_call\n";
|
||||
foreach my $func(@stubs)
|
||||
{
|
||||
print CODE <<"END";
|
||||
$func->{name}_fstats:
|
||||
istruc FuncStats
|
||||
at FuncStats.func_name, dd $func->{name}_name
|
||||
iend
|
||||
END
|
||||
}
|
||||
|
||||
my $num_funcs = (scalar @stubs);
|
||||
|
||||
print CODE <<"END";
|
||||
global _num_stubs
|
||||
_num_stubs: dd $num_funcs
|
||||
END
|
||||
|
||||
print CODE <<"END";
|
||||
section .text
|
||||
END
|
||||
|
||||
foreach my $func(@stubs)
|
||||
{
|
||||
if(defined $func->{params})
|
||||
{
|
||||
my $to_copy = $func->{params};
|
||||
|
||||
print CODE <<"END";
|
||||
global _$func->{name}
|
||||
_$func->{name}:
|
||||
; Check if we have address cached
|
||||
cmp dword [$func->{name}_addr], 0
|
||||
jne $func->{name}_go
|
||||
|
||||
; Fetch target function address
|
||||
push $func->{name}_target_func
|
||||
push dword $func->{target_dll_index}
|
||||
call _find_sym
|
||||
mov dword [$func->{name}_addr], eax
|
||||
|
||||
$func->{name}_go:
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
; Push tick count onto stack (ebp - 8)
|
||||
sub esp, 8
|
||||
push esp
|
||||
call _QueryPerformanceCounter\@4
|
||||
|
||||
; Copy original arguments ($to_copy bytes)
|
||||
END
|
||||
|
||||
for(; $to_copy >= 4;)
|
||||
{
|
||||
$to_copy -= 4;
|
||||
print CODE <<"END";
|
||||
push dword [ebp + 4 + 4 + $to_copy]
|
||||
END
|
||||
}
|
||||
|
||||
for(; $to_copy >= 2;)
|
||||
{
|
||||
$to_copy -= 2;
|
||||
print CODE <<"END";
|
||||
push word [ebp + 4 + 4 + $to_copy]
|
||||
END
|
||||
}
|
||||
|
||||
for(; $to_copy >= 1;)
|
||||
{
|
||||
$to_copy -= 1;
|
||||
print CODE <<"END";
|
||||
push byte [ebp + 4 + 4 + $to_copy]
|
||||
END
|
||||
}
|
||||
|
||||
print CODE <<"END";
|
||||
|
||||
; Call target function
|
||||
call [$func->{name}_addr]
|
||||
|
||||
; Push target function return value onto stack (ebp - 12)
|
||||
push eax
|
||||
|
||||
; Push tick count onto stack (ebp - 20)
|
||||
sub esp, 8
|
||||
push esp
|
||||
call _QueryPerformanceCounter\@4
|
||||
|
||||
; End tick parameter to _fprof_record_timed
|
||||
push dword ebp
|
||||
sub dword [esp], 20
|
||||
|
||||
; Start tick parameter to _fprof_record_untimed
|
||||
push dword ebp
|
||||
sub dword [esp], 8
|
||||
|
||||
; FuncStats parameter to _fprof_record_untimed
|
||||
push dword $func->{name}_fstats
|
||||
|
||||
; Record profiling data
|
||||
call _fprof_record_timed
|
||||
|
||||
add esp, 8 ; Pop end tick count
|
||||
pop eax ; Pop return value
|
||||
add esp, 8 ; Pop start tick count
|
||||
|
||||
pop ebp ; Restore caller's ebp
|
||||
|
||||
ret $func->{params}
|
||||
END
|
||||
}
|
||||
else{
|
||||
print CODE <<"END";
|
||||
global _$func->{name}
|
||||
_$func->{name}:
|
||||
; Check if we have address cached
|
||||
cmp dword [$func->{name}_addr], 0
|
||||
jne $func->{name}_go
|
||||
|
||||
; Fetch target function address
|
||||
push $func->{name}_target_func
|
||||
push dword $func->{target_dll_index}
|
||||
call _find_sym
|
||||
mov dword [$func->{name}_addr], eax
|
||||
|
||||
$func->{name}_go:
|
||||
|
||||
; Record that we were called
|
||||
push dword $func->{name}_fstats
|
||||
call _fprof_record_untimed
|
||||
|
||||
; Jump into target function. We have left the stack as we found it
|
||||
; so it can take over our frame.
|
||||
jmp [$func->{name}_addr]
|
||||
END
|
||||
}
|
||||
|
||||
print CODE "\tcmp\tdword [$f_name\_addr], 0\n";
|
||||
print CODE "\tjne\t$f_name\_jmp\n";
|
||||
|
||||
print CODE "\tpush\t$f_name\_sym\n";
|
||||
print CODE "\tpush\tdword ".$func->{"dllnum"}."\n";
|
||||
print CODE "\tcall\t_find_sym\n";
|
||||
print CODE "\tmov\t[$f_name\_addr], eax\n";
|
||||
|
||||
print CODE "\t$f_name\_jmp:\n";
|
||||
print CODE "\tjmp\t[$f_name\_addr]\n";
|
||||
}
|
||||
|
||||
close(CODE);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* IPXWrapper - Common functions
|
||||
* Copyright (C) 2011 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
* Copyright (C) 2011-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
enum ipx_log_level min_log_level = LOG_INFO;
|
||||
|
||||
/* Must be kept in sync with DLL_INDICES in mkstubs.pl! */
|
||||
static const char *dll_names[] = {
|
||||
"ipxwrapper.dll",
|
||||
"wsock32.dll",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* IPXWrapper - Common header
|
||||
* Copyright (C) 2011 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
* Copyright (C) 2011-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -24,6 +24,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "addr.h"
|
||||
#include "funcprof.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -39,6 +40,10 @@ enum ipx_log_level {
|
||||
|
||||
extern enum ipx_log_level min_log_level;
|
||||
|
||||
/* Defined by stubs */
|
||||
extern struct FuncStats stub_fstats[];
|
||||
extern unsigned int num_stubs;
|
||||
|
||||
const char *w32_error(DWORD errnum);
|
||||
|
||||
HKEY reg_open_main(bool readwrite);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ipxwrapper - DirectPlay service provider
|
||||
* Copyright (C) 2011 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
* Copyright (C) 2011-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -725,6 +725,8 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) {
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
if(fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
fprof_init(stub_fstats, num_stubs);
|
||||
|
||||
log_open("ipxwrapper.log");
|
||||
|
||||
min_log_level = get_main_config().log_level;
|
||||
@ -743,6 +745,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
|
||||
unload_dlls();
|
||||
log_close();
|
||||
|
||||
fprof_cleanup(stub_fstats, num_stubs);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1,9 +1,10 @@
|
||||
r_SPInit
|
||||
DPWS_GetEnumPort
|
||||
DPWS_BuildIPMessageHeader
|
||||
|
||||
WSACreateEvent:4
|
||||
WSACloseEvent:4
|
||||
WSAEventSelect:4
|
||||
WSAResetEvent:4
|
||||
WSASetEvent:4
|
||||
Function name Target DLL Target function
|
||||
------------------------------------------------------------
|
||||
r_SPInit dpwsockx.dll SPInit
|
||||
DPWS_GetEnumPort dpwsockx.dll DPWS_GetEnumPort
|
||||
DPWS_BuildIPMessageHeader dpwsockx.dll DPWS_BuildIPMessageHeader
|
||||
WSACreateEvent ws2_32.dll WSACreateEvent
|
||||
WSACloseEvent ws2_32.dll WSACloseEvent
|
||||
WSAEventSelect ws2_32.dll WSAEventSelect
|
||||
WSAResetEvent ws2_32.dll WSAResetEvent
|
||||
WSASetEvent ws2_32.dll WSASetEvent
|
||||
|
128
src/funcprof.c
Normal file
128
src/funcprof.c
Normal file
@ -0,0 +1,128 @@
|
||||
/* IPXWrapper - Function profiling functions
|
||||
* Copyright (C) 2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "funcprof.h"
|
||||
|
||||
void fprof_init(struct FuncStats *fstats, size_t n_fstats)
|
||||
{
|
||||
for(size_t i = 0; i < n_fstats; ++i)
|
||||
{
|
||||
fstats[i].min_time = 0.0;
|
||||
fstats[i].max_time = 0.0;
|
||||
fstats[i].total_time = 0.0;
|
||||
|
||||
fstats[i].n_calls = 0;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&(fstats[i].cs), 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
void fprof_cleanup(struct FuncStats *fstats, size_t n_fstats)
|
||||
{
|
||||
for(size_t i = 0; i < n_fstats; ++i)
|
||||
{
|
||||
DeleteCriticalSection(&(fstats[i].cs));
|
||||
}
|
||||
}
|
||||
|
||||
__stdcall void fprof_record_timed(struct FuncStats *fstats, const LARGE_INTEGER *start, const LARGE_INTEGER *end)
|
||||
{
|
||||
EnterCriticalSection(&(fstats->cs));
|
||||
|
||||
float this_time = end->QuadPart - start->QuadPart;
|
||||
|
||||
if(fstats->n_calls == 0)
|
||||
{
|
||||
fstats->min_time = this_time;
|
||||
fstats->max_time = this_time;
|
||||
fstats->total_time = this_time;
|
||||
}
|
||||
else{
|
||||
if(fstats->min_time > this_time)
|
||||
{
|
||||
fstats->min_time = this_time;
|
||||
}
|
||||
|
||||
if(fstats->max_time < this_time)
|
||||
{
|
||||
fstats->max_time = this_time;
|
||||
}
|
||||
|
||||
fstats->total_time += this_time;
|
||||
}
|
||||
|
||||
++(fstats->n_calls);
|
||||
|
||||
LeaveCriticalSection(&(fstats->cs));
|
||||
}
|
||||
|
||||
__stdcall void fprof_record_untimed(struct FuncStats *fstats)
|
||||
{
|
||||
EnterCriticalSection(&(fstats->cs));
|
||||
|
||||
++(fstats->n_calls);
|
||||
|
||||
LeaveCriticalSection(&(fstats->cs));
|
||||
}
|
||||
|
||||
void fprof_report(const char *dll_name, struct FuncStats *fstats, size_t n_fstats)
|
||||
{
|
||||
LARGE_INTEGER freq; /* TODO: Cache somewhere */
|
||||
QueryPerformanceFrequency(&freq);
|
||||
|
||||
const float TICKS_PER_USEC = freq.QuadPart / 1000000.0;
|
||||
|
||||
for(size_t i = 0; i < n_fstats; ++i)
|
||||
{
|
||||
EnterCriticalSection(&(fstats[i].cs));
|
||||
|
||||
float min_time = fstats[i].min_time;
|
||||
float max_time = fstats[i].max_time;
|
||||
float total_time = fstats[i].total_time;
|
||||
|
||||
unsigned int n_calls = fstats[i].n_calls;
|
||||
|
||||
fstats[i].n_calls = 0;
|
||||
|
||||
LeaveCriticalSection(&(fstats[i].cs));
|
||||
|
||||
if(n_calls > 0)
|
||||
{
|
||||
if(total_time > 0.0)
|
||||
{
|
||||
log_printf(LOG_INFO,
|
||||
"%s:%s was called %u times duration min %fus max %fus avg %fus",
|
||||
dll_name,
|
||||
fstats[i].func_name,
|
||||
n_calls,
|
||||
(min_time / TICKS_PER_USEC),
|
||||
(max_time / TICKS_PER_USEC),
|
||||
((total_time / (float)(n_calls)) / TICKS_PER_USEC));
|
||||
}
|
||||
else{
|
||||
log_printf(LOG_INFO,
|
||||
"%s:%s was called %u times",
|
||||
dll_name,
|
||||
fstats[i].func_name,
|
||||
n_calls);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
src/funcprof.h
Normal file
39
src/funcprof.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* IPXWrapper - Function profiling functions
|
||||
* Copyright (C) 2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef IPXWRAPPER_FUNCPROF_H
|
||||
#define IPXWRAPPER_FUNCPROF_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct FuncStats
|
||||
{
|
||||
const char *func_name;
|
||||
float min_time, max_time, total_time;
|
||||
unsigned int n_calls;
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
void fprof_init(struct FuncStats *fstats, size_t n_fstats);
|
||||
void fprof_cleanup(struct FuncStats *fstats, size_t n_fstats);
|
||||
|
||||
__stdcall void fprof_record_timed(struct FuncStats *fstats, const LARGE_INTEGER *start, const LARGE_INTEGER *end);
|
||||
__stdcall void fprof_record_untimed(struct FuncStats *fstats);
|
||||
|
||||
void fprof_report(const char *dll_name, struct FuncStats *fstats, size_t n_fstats);
|
||||
|
||||
#endif /* !IPXWRAPPER_FUNCPROF_H */
|
10
src/ipxconfig_stubs.txt
Normal file
10
src/ipxconfig_stubs.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Function name Target DLL Target function Parameters (bytes)
|
||||
-----------------------------------------------------------------------------
|
||||
pcap_open wpcap.dll pcap_open
|
||||
pcap_close wpcap.dll pcap_close
|
||||
pcap_findalldevs_ex wpcap.dll pcap_findalldevs_ex
|
||||
pcap_freealldevs wpcap.dll pcap_freealldevs
|
||||
pcap_getevent wpcap.dll pcap_getevent
|
||||
pcap_dispatch wpcap.dll pcap_dispatch
|
||||
pcap_geterr wpcap.dll pcap_geterr
|
||||
pcap_sendpacket wpcap.dll pcap_sendpacket
|
@ -1,5 +1,5 @@
|
||||
/* ipxwrapper - Library functions
|
||||
* Copyright (C) 2008-2014 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
* Copyright (C) 2008-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -63,6 +63,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
if(fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
fprof_init(stub_fstats, num_stubs);
|
||||
|
||||
log_open("ipxwrapper.log");
|
||||
|
||||
log_printf(LOG_INFO, "IPXWrapper %s", version_string);
|
||||
@ -136,6 +138,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
FreeLibrary(kernel32);
|
||||
kernel32 = NULL;
|
||||
}
|
||||
|
||||
fprof_cleanup(stub_fstats, num_stubs);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1,37 +1,48 @@
|
||||
inet_addr:4
|
||||
WSAStartup:4
|
||||
WSACleanup:4
|
||||
WSASetLastError:4
|
||||
WSAGetLastError:4
|
||||
htonl:4
|
||||
ntohl:4
|
||||
htons:4
|
||||
ntohs:4
|
||||
select:4
|
||||
r_listen:4
|
||||
r_accept:4
|
||||
WSACreateEvent:4
|
||||
WSAEventSelect:4
|
||||
WSACloseEvent:4
|
||||
WSAResetEvent:4
|
||||
WSASetEvent:4
|
||||
r_EnumProtocolsA:2
|
||||
r_EnumProtocolsW:2
|
||||
r_WSARecvEx:2
|
||||
r_bind:4
|
||||
r_closesocket:4
|
||||
r_getsockname:4
|
||||
r_getsockopt:4
|
||||
r_recv:4
|
||||
r_recvfrom:4
|
||||
r_sendto:4
|
||||
r_setsockopt:4
|
||||
r_shutdown:4
|
||||
r_socket:4
|
||||
r_ioctlsocket:4
|
||||
r_connect:4
|
||||
r_send:4
|
||||
r_getpeername:4
|
||||
inet_ntoa:4
|
||||
__WSAFDIsSet:4
|
||||
r_WSAAsyncSelect:4
|
||||
Function name Target DLL Target function Parameters (bytes)
|
||||
-------------------------------------------------------------------------------
|
||||
inet_addr ws2_32.dll inet_addr 4
|
||||
WSAStartup ws2_32.dll WSAStartup 8
|
||||
WSACleanup ws2_32.dll WSACleanup 0
|
||||
WSASetLastError ws2_32.dll WSASetLastError 4
|
||||
WSAGetLastError ws2_32.dll WSAGetLastError 0
|
||||
htonl ws2_32.dll htonl 4
|
||||
ntohl ws2_32.dll ntohl 4
|
||||
htons ws2_32.dll htons 4
|
||||
ntohs ws2_32.dll ntohs 4
|
||||
select ws2_32.dll select 20
|
||||
r_listen ws2_32.dll listen 8
|
||||
r_accept ws2_32.dll accept 12
|
||||
WSACreateEvent ws2_32.dll WSACreateEvent 0
|
||||
WSAEventSelect ws2_32.dll WSAEventSelect 12
|
||||
WSACloseEvent ws2_32.dll WSACloseEvent 4
|
||||
WSAResetEvent ws2_32.dll WSAResetEvent 4
|
||||
WSASetEvent ws2_32.dll WSASetEvent 4
|
||||
r_EnumProtocolsA mswsock.dll EnumProtocolsA 12
|
||||
r_EnumProtocolsW mswsock.dll EnumProtocolsW 12
|
||||
r_WSARecvEx mswsock.dll WSARecvEx 16
|
||||
r_bind ws2_32.dll bind 12
|
||||
r_closesocket ws2_32.dll closesocket 4
|
||||
r_getsockname ws2_32.dll getsockname 12
|
||||
r_getsockopt ws2_32.dll getsockopt 20
|
||||
r_recv ws2_32.dll recv 16
|
||||
r_recvfrom ws2_32.dll recvfrom 24
|
||||
r_sendto ws2_32.dll sendto 24
|
||||
r_setsockopt ws2_32.dll setsockopt 20
|
||||
r_shutdown ws2_32.dll shutdown 8
|
||||
r_socket ws2_32.dll socket 12
|
||||
r_ioctlsocket ws2_32.dll ioctlsocket 12
|
||||
r_connect ws2_32.dll connect 12
|
||||
r_send ws2_32.dll send 16
|
||||
r_getpeername ws2_32.dll getpeername 12
|
||||
inet_ntoa ws2_32.dll inet_ntoa 4
|
||||
__WSAFDIsSet ws2_32.dll __WSAFDIsSet 8
|
||||
r_WSAAsyncSelect ws2_32.dll WSAAsyncSelect 16
|
||||
|
||||
pcap_open wpcap.dll pcap_open
|
||||
pcap_close wpcap.dll pcap_close
|
||||
pcap_findalldevs_ex wpcap.dll pcap_findalldevs_ex
|
||||
pcap_freealldevs wpcap.dll pcap_freealldevs
|
||||
pcap_getevent wpcap.dll pcap_getevent
|
||||
pcap_dispatch wpcap.dll pcap_dispatch
|
||||
pcap_geterr wpcap.dll pcap_geterr
|
||||
pcap_sendpacket wpcap.dll pcap_sendpacket
|
||||
|
@ -1,35 +1,37 @@
|
||||
ServiceMain
|
||||
SvchostPushServiceGlobals
|
||||
AcceptEx
|
||||
EnumProtocolsA:0
|
||||
EnumProtocolsW:0
|
||||
GetAcceptExSockaddrs
|
||||
GetAddressByNameA
|
||||
GetAddressByNameW
|
||||
GetNameByTypeA
|
||||
GetNameByTypeW
|
||||
GetServiceA
|
||||
GetServiceW
|
||||
GetTypeByNameA
|
||||
GetTypeByNameW
|
||||
MigrateWinsockConfiguration
|
||||
NPLoadNameSpaces
|
||||
NSPStartup
|
||||
SetServiceA
|
||||
SetServiceW
|
||||
StartWsdpService
|
||||
StopWsdpService
|
||||
TransmitFile
|
||||
WSARecvEx:0
|
||||
WSPStartup
|
||||
dn_expand
|
||||
getnetbyname
|
||||
inet_network
|
||||
rcmd
|
||||
rexec
|
||||
rresvport
|
||||
s_perror
|
||||
sethostname
|
||||
inet_addr
|
||||
WSHEnumProtocols:0
|
||||
ntohs:1
|
||||
Function name Target DLL Target function Parameters (bytes)
|
||||
--------------------------------------------------------------------------------------------------
|
||||
ServiceMain mswsock.dll ServiceMain
|
||||
SvchostPushServiceGlobals mswsock.dll SvchostPushServiceGlobals
|
||||
AcceptEx mswsock.dll AcceptEx 32
|
||||
EnumProtocolsA ipxwrapper.dll EnumProtocolsA 12
|
||||
EnumProtocolsW ipxwrapper.dll EnumProtocolsW 12
|
||||
GetAcceptExSockaddrs mswsock.dll GetAcceptExSockaddrs 32
|
||||
GetAddressByNameA mswsock.dll GetAddressByNameA 40
|
||||
GetAddressByNameW mswsock.dll GetAddressByNameW 40
|
||||
GetNameByTypeA mswsock.dll GetNameByTypeA 12
|
||||
GetNameByTypeW mswsock.dll GetNameByTypeW 12
|
||||
GetServiceA mswsock.dll GetServiceA 28
|
||||
GetServiceW mswsock.dll GetServiceW 28
|
||||
GetTypeByNameA mswsock.dll GetTypeByNameA 8
|
||||
GetTypeByNameW mswsock.dll GetTypeByNameW 8
|
||||
MigrateWinsockConfiguration mswsock.dll MigrateWinsockConfiguration
|
||||
NPLoadNameSpaces mswsock.dll NPLoadNameSpaces
|
||||
NSPStartup mswsock.dll NSPStartup 8
|
||||
SetServiceA mswsock.dll SetServiceA 24
|
||||
SetServiceW mswsock.dll SetServiceW 24
|
||||
StartWsdpService mswsock.dll StartWsdpService
|
||||
StopWsdpService mswsock.dll StopWsdpService
|
||||
TransmitFile mswsock.dll TransmitFile 28
|
||||
WSARecvEx ipxwrapper.dll WSARecvEx 16
|
||||
WSPStartup mswsock.dll WSPStartup 76
|
||||
dn_expand mswsock.dll dn_expand
|
||||
getnetbyname mswsock.dll getnetbyname
|
||||
inet_network mswsock.dll inet_network
|
||||
rcmd mswsock.dll rcmd
|
||||
rexec mswsock.dll rexec
|
||||
rresvport mswsock.dll rresvport
|
||||
s_perror mswsock.dll s_perror
|
||||
sethostname mswsock.dll sethostname
|
||||
inet_addr mswsock.dll inet_addr 4
|
||||
WSHEnumProtocols ipxwrapper.dll WSHEnumProtocols 16
|
||||
ntohs wsock32.dll ntohs 4
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* IPXWrapper - Stub DLL functions
|
||||
* Copyright (C) 2008-2011 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
* Copyright (C) 2008-2019 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -21,10 +21,13 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "funcprof.h"
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
if(fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
fprof_init(stub_fstats, num_stubs);
|
||||
|
||||
log_open("ipxwrapper.log");
|
||||
|
||||
min_log_level = get_main_config().log_level;
|
||||
@ -43,6 +46,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
|
||||
unload_dlls();
|
||||
log_close();
|
||||
|
||||
fprof_cleanup(stub_fstats, num_stubs);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1,8 +0,0 @@
|
||||
pcap_open
|
||||
pcap_close
|
||||
pcap_findalldevs_ex
|
||||
pcap_freealldevs
|
||||
pcap_getevent
|
||||
pcap_dispatch
|
||||
pcap_geterr
|
||||
pcap_sendpacket
|
@ -1,76 +1,78 @@
|
||||
accept:0
|
||||
bind:0
|
||||
closesocket:0
|
||||
connect:0
|
||||
getpeername:0
|
||||
getsockname:0
|
||||
getsockopt:0
|
||||
htonl
|
||||
htons
|
||||
inet_addr
|
||||
inet_ntoa
|
||||
ioctlsocket:0
|
||||
listen:0
|
||||
ntohl
|
||||
ntohs
|
||||
recv:0
|
||||
recvfrom:0
|
||||
select
|
||||
send:0
|
||||
sendto:0
|
||||
setsockopt:0
|
||||
shutdown:0
|
||||
socket:0
|
||||
MigrateWinsockConfiguration
|
||||
gethostbyaddr
|
||||
gethostbyname
|
||||
getprotobyname
|
||||
getprotobynumber
|
||||
getservbyname
|
||||
getservbyport
|
||||
gethostname
|
||||
WSAAsyncSelect:0
|
||||
WSAAsyncGetHostByAddr
|
||||
WSAAsyncGetHostByName
|
||||
WSAAsyncGetProtoByNumber
|
||||
WSAAsyncGetProtoByName
|
||||
WSAAsyncGetServByPort
|
||||
WSAAsyncGetServByName
|
||||
WSACancelAsyncRequest
|
||||
WSASetBlockingHook
|
||||
WSAUnhookBlockingHook
|
||||
WSAGetLastError
|
||||
WSASetLastError
|
||||
WSACancelBlockingCall
|
||||
WSAIsBlocking
|
||||
WSAStartup
|
||||
WSACleanup
|
||||
__WSAFDIsSet
|
||||
WEP
|
||||
WSApSetPostRoutine
|
||||
inet_network
|
||||
getnetbyname
|
||||
rcmd
|
||||
rexec
|
||||
rresvport
|
||||
sethostname
|
||||
dn_expand
|
||||
WSARecvEx:0
|
||||
s_perror
|
||||
GetAddressByNameA
|
||||
GetAddressByNameW
|
||||
EnumProtocolsA:0
|
||||
EnumProtocolsW:0
|
||||
GetTypeByNameA
|
||||
GetTypeByNameW
|
||||
GetNameByTypeA
|
||||
GetNameByTypeW
|
||||
SetServiceA
|
||||
SetServiceW
|
||||
GetServiceA
|
||||
GetServiceW
|
||||
NPLoadNameSpaces
|
||||
TransmitFile
|
||||
AcceptEx
|
||||
GetAcceptExSockaddrs
|
||||
WSHEnumProtocols:0
|
||||
Function name Target DLL Target function Parameters (bytes)
|
||||
--------------------------------------------------------------------------------------------------
|
||||
accept ipxwrapper.dll accept 12
|
||||
bind ipxwrapper.dll bind 12
|
||||
closesocket ipxwrapper.dll closesocket 4
|
||||
connect ipxwrapper.dll connect 12
|
||||
getpeername ipxwrapper.dll getpeername 12
|
||||
getsockname ipxwrapper.dll getsockname 12
|
||||
getsockopt ipxwrapper.dll getsockopt 20
|
||||
htonl wsock32.dll htonl 4
|
||||
htons wsock32.dll htons 4
|
||||
inet_addr wsock32.dll inet_addr 4
|
||||
inet_ntoa wsock32.dll inet_ntoa 4
|
||||
ioctlsocket ipxwrapper.dll ioctlsocket 12
|
||||
listen ipxwrapper.dll listen 8
|
||||
ntohl wsock32.dll ntohl 4
|
||||
ntohs wsock32.dll ntohs 4
|
||||
recv ipxwrapper.dll recv 16
|
||||
recvfrom ipxwrapper.dll recvfrom 24
|
||||
select wsock32.dll select 20
|
||||
send ipxwrapper.dll send 16
|
||||
sendto ipxwrapper.dll sendto 24
|
||||
setsockopt ipxwrapper.dll setsockopt 20
|
||||
shutdown ipxwrapper.dll shutdown 8
|
||||
socket ipxwrapper.dll socket 12
|
||||
MigrateWinsockConfiguration wsock32.dll MigrateWinsockConfiguration
|
||||
gethostbyaddr wsock32.dll gethostbyaddr 12
|
||||
gethostbyname wsock32.dll gethostbyname 4
|
||||
getprotobyname wsock32.dll getprotobyname 4
|
||||
getprotobynumber wsock32.dll getprotobynumber 4
|
||||
getservbyname wsock32.dll getservbyname 8
|
||||
getservbyport wsock32.dll getservbyport 8
|
||||
gethostname wsock32.dll gethostname 8
|
||||
WSAAsyncSelect ipxwrapper.dll WSAAsyncSelect 16
|
||||
WSAAsyncGetHostByAddr wsock32.dll WSAAsyncGetHostByAddr 28
|
||||
WSAAsyncGetHostByName wsock32.dll WSAAsyncGetHostByName 20
|
||||
WSAAsyncGetProtoByNumber wsock32.dll WSAAsyncGetProtoByNumber 20
|
||||
WSAAsyncGetProtoByName wsock32.dll WSAAsyncGetProtoByName 20
|
||||
WSAAsyncGetServByPort wsock32.dll WSAAsyncGetServByPort 24
|
||||
WSAAsyncGetServByName wsock32.dll WSAAsyncGetServByName 24
|
||||
WSACancelAsyncRequest wsock32.dll WSACancelAsyncRequest 4
|
||||
WSASetBlockingHook wsock32.dll WSASetBlockingHook 4
|
||||
WSAUnhookBlockingHook wsock32.dll WSAUnhookBlockingHook 0
|
||||
WSAGetLastError wsock32.dll WSAGetLastError 0
|
||||
WSASetLastError wsock32.dll WSASetLastError 4
|
||||
WSACancelBlockingCall wsock32.dll WSACancelBlockingCall 0
|
||||
WSAIsBlocking wsock32.dll WSAIsBlocking 0
|
||||
WSAStartup wsock32.dll WSAStartup 8
|
||||
WSACleanup wsock32.dll WSACleanup 0
|
||||
__WSAFDIsSet wsock32.dll __WSAFDIsSet 8
|
||||
WEP wsock32.dll WEP
|
||||
WSApSetPostRoutine wsock32.dll WSApSetPostRoutine
|
||||
inet_network wsock32.dll inet_network
|
||||
getnetbyname wsock32.dll getnetbyname
|
||||
rcmd wsock32.dll rcmd
|
||||
rexec wsock32.dll rexec
|
||||
rresvport wsock32.dll rresvport
|
||||
sethostname wsock32.dll sethostname
|
||||
dn_expand wsock32.dll dn_expand
|
||||
WSARecvEx ipxwrapper.dll WSARecvEx 16
|
||||
s_perror wsock32.dll s_perror
|
||||
GetAddressByNameA wsock32.dll GetAddressByNameA 40
|
||||
GetAddressByNameW wsock32.dll GetAddressByNameW 40
|
||||
EnumProtocolsA ipxwrapper.dll EnumProtocolsA 12
|
||||
EnumProtocolsW ipxwrapper.dll EnumProtocolsW 12
|
||||
GetTypeByNameA wsock32.dll GetTypeByNameA 8
|
||||
GetTypeByNameW wsock32.dll GetTypeByNameW 8
|
||||
GetNameByTypeA wsock32.dll GetNameByTypeA 12
|
||||
GetNameByTypeW wsock32.dll GetNameByTypeW 12
|
||||
SetServiceA wsock32.dll SetServiceA 24
|
||||
SetServiceW wsock32.dll SetServiceW 24
|
||||
GetServiceA wsock32.dll GetServiceA 28
|
||||
GetServiceW wsock32.dll GetServiceW 28
|
||||
NPLoadNameSpaces wsock32.dll NPLoadNameSpaces
|
||||
TransmitFile wsock32.dll TransmitFile 28
|
||||
AcceptEx wsock32.dll AcceptEx 32
|
||||
GetAcceptExSockaddrs wsock32.dll GetAcceptExSockaddrs 32
|
||||
WSHEnumProtocols ipxwrapper.dll WSHEnumProtocols 16
|
||||
|
Loading…
x
Reference in New Issue
Block a user