Skip to content

Commit bfc11cc

Browse files
authored
add a cliloader option to bypass loading the intercept DLL (#345)
This can be useful if cliloader is only used as a mechanism to conveniently set controls, and another install mechanism (like the "local install") is used to load the intercept DLL itself.
1 parent 9368edb commit bfc11cc

File tree

1 file changed

+80
-68
lines changed

1 file changed

+80
-68
lines changed

cliloader/cliloader.cpp

Lines changed: 80 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ static void getCommandLine(char *argv[], int startArg)
9696
#define GETENV( _name, _value ) _dupenv_s( &_value, NULL, _name )
9797
#define FREEENV( _value ) free( _value )
9898

99+
bool do_DLL_load = true;
100+
99101
#else
100102

101103
#include <limits.h>
@@ -379,7 +381,12 @@ static bool parseArguments(int argc, char *argv[])
379381
printMetrics();
380382
return false;
381383
}
382-
#if !defined(_WIN32)
384+
#if defined(_WIN32)
385+
else if( !strcmp(argv[i], "--no-DLL-load") )
386+
{
387+
do_DLL_load = false;
388+
}
389+
#else // not Windows
383390
else if( !strcmp(argv[i], "--no-LD_PRELOAD") )
384391
{
385392
set_LD_PRELOAD = false;
@@ -560,7 +567,9 @@ static bool parseArguments(int argc, char *argv[])
560567
" --debug Enable cliloader Debug Messages\n"
561568
" --controls Print All Controls and Exit\n"
562569
" --metrics Print All MDAPI Metrics and Exit\n"
563-
#if !defined(_WIN32)
570+
#if defined(_WIN32)
571+
" --no-DLL-load Do not load the Intercept DLL into the child process\n"
572+
#else // not Windows
564573
" --no-LD_PRELOAD Do not set LD_PRELOAD\n"
565574
" --no-LD_LIBRARY_PATH Do not set LD_LIBRARY_PATH\n"
566575
#endif
@@ -684,80 +693,83 @@ int main(int argc, char *argv[])
684693
// There is no 32-bit and 64-bit mismatch.
685694
// Start intercepting.
686695

687-
// Allocate child memory for the full DLL path:
688-
void *childPath = VirtualAllocEx(
689-
pinfo.hProcess,
690-
NULL,
691-
dllpath.size() + 1,
692-
MEM_COMMIT,
693-
PAGE_READWRITE );
694-
if( childPath == NULL )
696+
if( do_DLL_load )
695697
{
696-
die("allocating child memory");
697-
}
698-
DEBUG("allocated child memory\n");
699-
700-
// Write DLL path to child:
701-
if( WriteProcessMemory(
698+
// Allocate child memory for the full DLL path:
699+
void *childPath = VirtualAllocEx(
702700
pinfo.hProcess,
703-
childPath,
704-
(void*)dllpath.c_str(),
701+
NULL,
705702
dllpath.size() + 1,
706-
NULL ) == FALSE )
707-
{
708-
die("writing child memory");
709-
}
710-
DEBUG("wrote dll path to child memory\n");
703+
MEM_COMMIT,
704+
PAGE_READWRITE );
705+
if( childPath == NULL )
706+
{
707+
die("allocating child memory");
708+
}
709+
DEBUG("allocated child memory\n");
710+
711+
// Write DLL path to child:
712+
if( WriteProcessMemory(
713+
pinfo.hProcess,
714+
childPath,
715+
(void*)dllpath.c_str(),
716+
dllpath.size() + 1,
717+
NULL ) == FALSE )
718+
{
719+
die("writing child memory");
720+
}
721+
DEBUG("wrote dll path to child memory\n");
711722

712-
// Create a thread to load the intercept DLL in the child process:
713-
HANDLE childThread = CreateRemoteThread(
714-
pinfo.hProcess,
715-
NULL,
716-
0,
717-
(LPTHREAD_START_ROUTINE)GetProcAddress(
718-
GetModuleHandleA("kernel32.dll"),
719-
"LoadLibraryA"),
720-
childPath,
721-
0,
722-
NULL );
723-
if( childThread == NULL )
724-
{
725-
die("loading DLL in child process");
726-
}
727-
DEBUG("created child thread to load DLL\n");
723+
// Create a thread to load the intercept DLL in the child process:
724+
HANDLE childThread = CreateRemoteThread(
725+
pinfo.hProcess,
726+
NULL,
727+
0,
728+
(LPTHREAD_START_ROUTINE)GetProcAddress(
729+
GetModuleHandleA("kernel32.dll"),
730+
"LoadLibraryA"),
731+
childPath,
732+
0,
733+
NULL );
734+
if( childThread == NULL )
735+
{
736+
die("loading DLL in child process");
737+
}
738+
DEBUG("created child thread to load DLL\n");
728739

729-
// Wait for child thread to complete:
730-
if( WaitForSingleObject(childThread, INFINITE) != WAIT_OBJECT_0 )
731-
{
732-
die("waiting for DLL loading");
733-
}
734-
DEBUG("child thread to load DLL completed\n");
735-
CloseHandle(childThread);
736-
VirtualFreeEx(pinfo.hProcess, childPath, dllpath.size() + 1, MEM_RELEASE);
737-
DEBUG("cleaned up child thread to load DLL\n");
740+
// Wait for child thread to complete:
741+
if( WaitForSingleObject(childThread, INFINITE) != WAIT_OBJECT_0 )
742+
{
743+
die("waiting for DLL loading");
744+
}
745+
DEBUG("child thread to load DLL completed\n");
746+
CloseHandle(childThread);
747+
VirtualFreeEx(pinfo.hProcess, childPath, dllpath.size() + 1, MEM_RELEASE);
748+
DEBUG("cleaned up child thread to load DLL\n");
738749

739-
childThread = CreateRemoteThread(
740-
pinfo.hProcess,
741-
NULL,
742-
0,
743-
cliprof_init,
744-
NULL,
745-
0,
746-
NULL );
747-
if( childThread == NULL )
748-
{
749-
die("replacing functions in child thread");
750-
}
751-
DEBUG("created child thread to replace functions\n");
750+
childThread = CreateRemoteThread(
751+
pinfo.hProcess,
752+
NULL,
753+
0,
754+
cliprof_init,
755+
NULL,
756+
0,
757+
NULL );
758+
if( childThread == NULL )
759+
{
760+
die("replacing functions in child thread");
761+
}
762+
DEBUG("created child thread to replace functions\n");
752763

753-
// Wait for child thread to complete:
754-
if( WaitForSingleObject(childThread, INFINITE) != WAIT_OBJECT_0 )
755-
{
756-
die("waiting for initialization thread");
764+
// Wait for child thread to complete:
765+
if( WaitForSingleObject(childThread, INFINITE) != WAIT_OBJECT_0 )
766+
{
767+
die("waiting for initialization thread");
768+
}
769+
DEBUG("child thread to replace functions completed\n");
770+
CloseHandle(childThread);
771+
DEBUG("cleaned up child thread to replace functions\n");
757772
}
758-
DEBUG("child thread to replace functions completed\n");
759-
CloseHandle(childThread);
760-
DEBUG("cleaned up child thread to replace functions\n");
761773
}
762774

763775
FreeModule(dll);

0 commit comments

Comments
 (0)