In Debug it works but not in Release.

J

jt

For some stupid reason, I can't get this to work in Release mode, but works
well in Debug mode.

Below is the function:

Here is the line:
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this doesn't find
the match, but in debug mode it does

See strpos prototype below this
---------------------------------------------------------------------------------
int OnSelchangeProcesses(DWORD dwProcessID, STRING cmdLineStr)
{
DWORD dwSize;
PROCESS_BASIC_INFORMATION pbi;
NTQIP *lpfnNtQueryInformationProcess;
__PEB PEB;
__INFOBLOCK Block;
TCHAR *pszCmdLine = NULL;

int pos;

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, dwProcessID);
if (NULL != hProcess)
{
pbi.PebBaseAddress = (_PEB *) 0x7ffdf000;

// we'll default to the above address, but newer OSs might have
a different
// base address for the PEB
HMODULE hLibrary = GetModuleHandle(_T("ntdll.dll"));
if (NULL != hLibrary)
{
lpfnNtQueryInformationProcess = (NTQIP *)
GetProcAddress(hLibrary, "ZwQueryInformationProcess");
if (NULL != lpfnNtQueryInformationProcess)
(*lpfnNtQueryInformationProcess)(hProcess,
ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);
}

BOOL bSuccess = ReadProcessMemory(hProcess, pbi.PebBaseAddress,
&PEB, sizeof(PEB), &dwSize);

if (bSuccess != FALSE)
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
PEB.dwInfoBlockAddress, &Block, sizeof(Block), &dwSize);

pszCmdLine = new TCHAR[Block.wMaxLength];
}

if (bSuccess != FALSE)
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
Block.dwCmdLineAddress, pszCmdLine, Block.wMaxLength, &dwSize);
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this doesn't find
the match, but in debug mode it does
printf("%d\n",pos);
if (pos >= 0 )
_tprintf(TEXT("%s\n"),pszCmdLine);
}

if (NULL != pszCmdLine)
delete [] pszCmdLine;

CloseHandle(hProcess);
}

return pos;
}

I found this on the internet.
-----------------------------------------------------------------------------------------

#ifndef UNICODE
# define TCHAR char
# define STRING char *
#else
# ifndef TCHAR
# define TCHAR wchar_t
# endif /* TCHAR */
# define STRING wchar_t *
#endif /* UNICODE */

int strpos( STRING haystack, STRING needle )
{
STRING pDest;
int position;

#ifdef DEBUG_VERBOSE
TCHAR lpBuf[1024];
#endif /* def DEBUG_VERBOSE */

#ifndef UNICODE
pDest = (STRING) strstr( haystack, needle );
#else
pDest = (STRING) wcsstr( haystack, needle );
#endif /* UNICODE */

if( pDest )
position = pDest - haystack;
else
{
#ifdef DEBUG_VERBOSE
# ifdef UNICODE
printf( L"strpos(): Could not find '%s' in '%s'.\tFAIL.", needle,
haystack );
# else
printf( "strpos(): Could not find '%s' in '%s'.\tFAIL.", needle,
haystack );
# endif /* def UNICODE */
#endif /* def DEBUG_VERBOSE */
return -1;
}

#ifdef DEBUG_VERBOSE
# ifdef UNICODE
printf( L"strpos(): Found '%s' at position: %d.\t\tOK.", needle,
position );
# else
printf( "strpos(): Found '%s' at position: %d.\t\tOK.", needle,
position );
# endif /* def UNICODE */
#endif /* def DEBUG_VERBOSE */

return position;
}
 
V

Vladimir S. Oka

jt said:
For some stupid reason, I can't get this to work in Release mode, but works
well in Debug mode.

Below is the function:

Here is the line:
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this doesn't find
the match, but in debug mode it does

The code you post below sems to be C++, and not C (the giveaway is the
line using `new` operator). Also, the code is chock-full of
non-standard types and functions, and you don't tell us what these are,
and do. E.g. how do we know whether the call to `ReadProcessMemory`
just before the line that worries you does not mess up the
`pszCmdLine`, which is presumably a pointer to a null-terminated
string? Therein, actually, may lie your problem: you do not test
bSuccess.

In any case, comp.lang.c++, or even better, one of the OS or
implementation specific groups would be a much better place for you to
ask this question.
See strpos prototype below this
---------------------------------------------------------------------------------
int OnSelchangeProcesses(DWORD dwProcessID, STRING cmdLineStr)
{
DWORD dwSize;
PROCESS_BASIC_INFORMATION pbi;
NTQIP *lpfnNtQueryInformationProcess;
__PEB PEB;
__INFOBLOCK Block;
TCHAR *pszCmdLine = NULL;

int pos;

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, dwProcessID);
if (NULL != hProcess)
{
pbi.PebBaseAddress = (_PEB *) 0x7ffdf000;

// we'll default to the above address, but newer OSs might have
a different
// base address for the PEB
HMODULE hLibrary = GetModuleHandle(_T("ntdll.dll"));
if (NULL != hLibrary)
{
lpfnNtQueryInformationProcess = (NTQIP *)
GetProcAddress(hLibrary, "ZwQueryInformationProcess");
if (NULL != lpfnNtQueryInformationProcess)
(*lpfnNtQueryInformationProcess)(hProcess,
ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);
}

BOOL bSuccess = ReadProcessMemory(hProcess, pbi.PebBaseAddress,
&PEB, sizeof(PEB), &dwSize);

if (bSuccess != FALSE)
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
PEB.dwInfoBlockAddress, &Block, sizeof(Block), &dwSize);

pszCmdLine = new TCHAR[Block.wMaxLength];
}

if (bSuccess != FALSE)
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
Block.dwCmdLineAddress, pszCmdLine, Block.wMaxLength, &dwSize);
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this doesn't find
the match, but in debug mode it does
printf("%d\n",pos);
if (pos >= 0 )
_tprintf(TEXT("%s\n"),pszCmdLine);
}

if (NULL != pszCmdLine)
delete [] pszCmdLine;

CloseHandle(hProcess);
}

return pos;
}

I found this on the internet.
-----------------------------------------------------------------------------------------

#ifndef UNICODE
# define TCHAR char
# define STRING char *
#else
# ifndef TCHAR
# define TCHAR wchar_t
# endif /* TCHAR */
# define STRING wchar_t *
#endif /* UNICODE */

int strpos( STRING haystack, STRING needle )
{
STRING pDest;
int position;

#ifdef DEBUG_VERBOSE
TCHAR lpBuf[1024];
#endif /* def DEBUG_VERBOSE */

#ifndef UNICODE
pDest = (STRING) strstr( haystack, needle );
#else
pDest = (STRING) wcsstr( haystack, needle );
#endif /* UNICODE */

if( pDest )
position = pDest - haystack;
else
{
#ifdef DEBUG_VERBOSE
# ifdef UNICODE
printf( L"strpos(): Could not find '%s' in '%s'.\tFAIL.", needle,
haystack );
# else
printf( "strpos(): Could not find '%s' in '%s'.\tFAIL.", needle,
haystack );
# endif /* def UNICODE */
#endif /* def DEBUG_VERBOSE */
return -1;
}

#ifdef DEBUG_VERBOSE
# ifdef UNICODE
printf( L"strpos(): Found '%s' at position: %d.\t\tOK.", needle,
position );
# else
printf( "strpos(): Found '%s' at position: %d.\t\tOK.", needle,
position );
# endif /* def UNICODE */
#endif /* def DEBUG_VERBOSE */

return position;
}
 
C

CBFalconer

jt said:
For some stupid reason, I can't get this to work in Release mode,
but works well in Debug mode.

Below is the function:

Here is the line:
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this
doesn't find the match, but in debug mode it does

See strpos prototype below this
---------------------------------------------------------------------------------
int OnSelchangeProcesses(DWORD dwProcessID, STRING cmdLineStr)
{
DWORD dwSize;
PROCESS_BASIC_INFORMATION pbi;
NTQIP *lpfnNtQueryInformationProcess;
__PEB PEB;
__INFOBLOCK Block;
TCHAR *pszCmdLine = NULL;
.... snip ...

If you want help here on this you must first get rid of (or define)
the undefined items, such as DWORD, STRING, PROCESS_*, NTQIO, and
especially the illegal identifiers __PEB, __INFOBLOCK, etc. Those
identifiers are reserved for the implementation.

If you are depending on some non-standard system, you should seek a
newsgroup that deals with that non-standard system. Here we deal
only with ISO C, so that all questions can ultimately be resolved
by reading the standard.

In general, when things work while including debug information, and
not otherwise, it indicates some sort of undefined (or possibly
system) defined behaviour, and thus a mistake in your code.

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
<http://clc-wiki.net> (C-info)
 
D

Dave Thompson

if (bSuccess != FALSE)

Aside: although you don't provide the definitions of BOOL and FALSE,
if they are at all reasonable this is equivalent to if (bSuccess)
which is easier to write and more important IMO easier to read.
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
PEB.dwInfoBlockAddress, &Block, sizeof(Block), &dwSize);

pszCmdLine = new TCHAR[Block.wMaxLength];
}

if (bSuccess != FALSE)
{
bSuccess = ReadProcessMemory(hProcess, (LPVOID)
Block.dwCmdLineAddress, pszCmdLine, Block.wMaxLength, &dwSize);
pos=strpos(pszCmdLine,cmdLineStr); // in release mode this doesn't find
the match, but in debug mode it does

As noted elsethread 'new' is C++ not C. But if you replace it by the
functionally equivalent malloc, I'd bet up to 3 cents that your
ReadProcessMemory reads exactly Block.wMaxLength nonnull characters
into it, not forming a valid nullterminated string as required by
strstr and thus strpos. Instead it will run off into unallocated
memory whose contents may very well differ betwen debug and release.

Aside: I don't think this code works for Unicode, which wastes all the
effort and clutter elsewhere in your program to handle that.
printf("%d\n",pos);
if (pos >= 0 )
_tprintf(TEXT("%s\n"),pszCmdLine);

Assuming this actually maps to or emulates printf, again a good bet,
this also requires a null-terminated string.
}

if (NULL != pszCmdLine)
delete [] pszCmdLine;
The test is unnecessary (but harmless); delete null in C++ and
free(null) in either C or C++ are guaranteed safe no-ops.

int strpos( STRING haystack, STRING needle )

'int' is not guaranteed large enough to represent offsets within an
object, in this case specifically within a string. ptrdiff_t would be
the better standard solution, or ssize_t in POSIX.


- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top