Dan Farmer's book talks about using a customized strcmp to reveal a hacking program's embedded password. I thought I could do the same here. Combine with strcmp's original code (from http://www.cs.umb.edu/ulab/pclibsrc/). The example is given on Linux. Windows systems programmers are very familiar with the concept too, and call it DLL Injection. $ cat strcmp.c int strcmp(const char *s1, const char *s2) { printf("strcmp call arguments: \"%s\" and \"%s\"\n", s1, s2); while (*s1 == *s2++) if (*s1++=='\0') return(0); return(*s1 - *--s2); } #The following gcc command may need -fno-builtin or -fno-builtin-printf; if you must compile with -fPIC, then the whole thing won't work $ gcc --shared -o strcmp.so strcmp.c $ LD_PRELOAD=`pwd`/strcmp.so sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Mon May 12 14:34:22 2008 Copyright (c) 1982, 2005, Oracle. All rights reserved. strcmp call arguments: "default" and "allcomp" strcmp call arguments: "default" and "allcomp" strcmp call arguments: "dba" and "root" strcmp call arguments: "dba" and "bin" ... strcmp call arguments: "dba" and "cvscp" strcmp call arguments: "dba" and "dba" Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, Real Application Clusters, OLAP and Data Mining options SQL> So you see sqlplus actually has a lot of strcmp() calls. We print what it compares and let it continue. However, this only works if the program prints to stdout. If we want to print to something else, we have to change our printf to fprintf whose first arg points to that something else. This is needed because Oracle server or background processes run like daemons, which have no attached terminals. I noticed that all those processes have file descriptor 5 opened as their trace file, or /dev/null as fd 5: $ lsof -p 18601 -a -d 5 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME oracle 18601 oracle 5w REG 253,0 897 9094187 /home/oracle/admin/ORCL/udump/boy_ora_18525.trc $ lsof -p 18930 -a -d 5 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME oracle 18930 oracle 5r CHR 1,3 1544 /dev/null So let's modify strcmp.c as follows: $ cat strcmp.c #include int strcmp(const char *s1, const char *s2) { FILE *F=fdopen(5, "w"); fprintf(F, "strcmp call arguments: \"%s\" and \"%s\"\n", s1, s2); while (*s1 == *s2++) if (*s1++=='\0') return(0); return(*s1 - *--s2); } $ gcc --shared -o strcmp.so strcmp.c $ LD_PRELOAD=`pwd`/strcmp.so sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Mon May 12 14:47:33 2008 Copyright (c) 1982, 2005, Oracle. All rights reserved. ERROR: ORA-12547: TNS:lost contact Enter user-name: Unfortunately, sqlplus won't allow you to print anything to fd 5, at least not during the initial connection. So let's open our own log file: $ cat strcmp.c #include int strcmp(const char *s1, const char *s2) { FILE *F=fopen("/home/oracle/yong/misc.log", "a"); fprintf(F, "strcmp call arguments: \"%s\" and \"%s\"\n", s1, s2); fclose(F); while (*s1 == *s2++) if (*s1++=='\0') return(0); return(*s1 - *--s2); } After gcc and LD_PRELOAD=... sqlplus / as sysdba, we're in, and we see plenty of string comparisons that were done. The same can be done for memcpy: #include void memcpy(char *s1, char *s2, int n) { FILE *F=fopen("/home/oracle/yong/misc.log", "a"); fprintf(F, "memcpy: \"%s\" and \"%s\"\n", s1, s2); fclose(F); while (n--) *s1++ = *s2++; }