IMG

 
IMG
IMG   IMG
  Welcome to GTAForums! Be sure to check out the Grand Theft Auto V Forum.

You are not registered! (If you are, click here to login) Registering is fast, free and easy and allows you to instantly reply to any topic on GTAForums.
Why wait? Click here to register your own unique username and become part of the ever-growing community!


( Log In | Register | Revalidate Validation E-mail )
Quick Log-In:
  IMG
       
>
  Reply to this topicStart new topicStart Poll

 Problem with OutputDebugString()

 type cast issue
 
ghost of delete key  
Posted: Monday, Feb 1 2010, 11:58
Quote Post


ಠ_ಠ ... otter ...
Group Icon
Group: The Connection
Joined: Dec 27, 2003

gadsden.gif

Member Award




I'm trying to recompile (i)dle's old vcdbg source (Vice City Debug) which outputs hidden debug messages for capture (using DebugView).

I'm using (yak!) Visual C++ 2010 Express...
The original was compiled with VC6, I believe.

Anyway, the original declares a printout function...
CODE

void __cdecl OurDebugPrintf(char *szFormat, ...)
{
char chBuffer[256];

va_list v;
va_start(v, szFormat);
_vsnprintf(chBuffer, 255, szFormat, v);
chBuffer[255] = '\0';
OutputDebugString(chBuffer);
}


... and the hook procedure defines 3 vectors into the exe: (one shown for clarity)

CODE

void Hookin()
{
try {
 // forces the linking of the floating point library.
 char chBuffer[80];
 sprintf(chBuffer, "%f", 3.14);  

 ////

 DWORD nOrgProtect;

 // mod stub_printf function
 {
  BYTE *p = (BYTE *) 0x401000;
  VirtualProtect(p, 16, PAGE_READWRITE, &nOrgProtect);
  *p = 0x68; // push
  *(DWORD *)(p + 1) = (DWORD) OurDebugPrintf;
  *(p + 5) = 0xc3; // ret
 }
.
.
.
} catch(...) {
 OutputDebugString("vcdbg caught exception when hooking");
}
}


Anyway, the originally compiled .asi works fine. The problem is, when this is compiled in VC2010, you get a type error for OutputDebugString(), saying that char and LPCSTR aren't compatible. (duh!)

So, I tried casting to LPCSTR like so:
CODE

OutputDebugString(LPCSTR(chBuffer));
.
.
.
OutputDebugString(LPCSTR("vcdbg caught exception when hooking"));

which compiled without complaint, but output was garbage.

So, I found that OutputDebugString() seems to be a holdover from old stuff, it calls by default OutputDebugStringW(), which of course wants a LPCSTR.
So I tried:
CODE

OutputDebugStringA(chBuffer);
.
.
.
OutputDebugStringA("vcdbg caught exception when hooking");

since it wants a char, which again compiled nicely, and got exactly the same garbage.

What am I missing? mercie_blink.gif I know it's something fundamental. Well ok, no fun and all mental, but still...

This is what it should look like:
CODE

[2556] Default skin set as no other skins are available OR saved skin not found!
[2556] Performance counter available
[2556] vcdbg process attach
[2556] Finding MP3s...
[2556] C:\program files\Rockstar Games\Grand Theft Auto Vice City DEV\MP3\
[2556] C:\program files\Rockstar Games\Grand Theft Auto Vice City DEV\MP3\. - NOT A VALID MP3
[2556] C:\program files\Rockstar Games\Grand Theft Auto Vice City DEV\MP3\.. - NOT A VALID MP3
[2556] C:\program files\Rockstar Games\Grand Theft Auto Vice City DEV\MP3\MP3Report.txt - NOT A VALID MP3
[2556] Available video memory 200108992
[2556] Initialising CParticleMgr...
[2556] Initialising CParticle...
[2556] CParticle ready
[2556] sizeof SimpleModelStore 264184
[2556] sizeof TimeModelStore 30804


but this is what I get:
CODE

[1956] Default skin set as no other skins are available OR saved skin not found!
[1956] Performance counter available
[1956] ??????????
[1956] ??????????
[1956] Finding MP3s...
[1956] C:\program files\Rockstar Games\Grand Theft Auto Vice City\MP3\
[1956] C:\program files\Rockstar Games\Grand Theft Auto Vice City\MP3\. - NOT A VALID MP3
[1956] C:\program files\Rockstar Games\Grand Theft Auto Vice City\MP3\.. - NOT A VALID MP3
[1956] C:\program files\Rockstar Games\Grand Theft Auto Vice City\MP3\MP3Report.txt - NOT A VALID MP3
[1956] ????????????????
[1956] ?????????????????????????????????????????????????????????????????????????????????????ŝ????
[1956] ??????????????????????????????????????????????????????????????????????????????????????????ŝ????
[1956] ????????????.??????????????????????????????????????????????????????????????????????????????ŝ????


Note that the lines you CAN read are not processed by the hook.

BTW, The compiler informs me that _vsnprintf() is now considered unsafe.
Using _vsnprintf_s() in both of the mentioned cases made no difference, it only made the compiler happy.

So tell me just how I'm a dummy. I gotta learn this sh!t, and all I got is a crappy SAMS book, and far too little time to access the web.

This post has been edited by ghost of delete key on Monday, Feb 1 2010, 12:26
Users WebsitePM
  Top
 

 
Andrew  
Posted: Wednesday, Feb 3 2010, 08:24
Quote Post



Group Icon
Group: Forum Admins
Joined: Jul 21, 2003

Member Award




I remember having huge problems with something similar to this, but it was a while ago so I've forgotten how to solve it. I think I had to change the project char type in the settings on Visual Studio.

If it defaults to using
CODE

OutputDebugStringW()


Then couldn't you use that?
PM
  Top
 

 
ghost of delete key  
Posted: Wednesday, Feb 3 2010, 13:20
Quote Post


ಠ_ಠ ... otter ...
Group Icon
Group: The Connection
Joined: Dec 27, 2003

gadsden.gif

Member Award




Already tried that... see OP. tounge.gif

This link is the most informative thing I've found,
but it doesn't explain what the trouble could be.

In the part about reversing KERNEL32.DLL, they mentioned:
QUOTE
Oddly enough, we found that OutputDebugString() is not a native Unicode function. Most of the Win32 API has the "real" function to use Unicode (the "W" version), and they automatically convert from ASCII to UNICODE if the "A" version of the function is called.

But since OutputDebugString ultimately passes data to the debugger in the memory buffer strictly as ASCII, they have inverted the usual A/W pairing. This suggests that for sending a quick message to a debugger even in a Unicode program, it can be done by calling the "A" version directly


Funny then that the depricated OutputDebugString() calls OutputDebugStringW(), which then calls OutputDebugStringA() !!

Anyway, that's what I find with VC2010.

Maybe I should go to the trouble of trying to compile this in DevC++.
It's so half-ass-and-wacky, very little more than small examples ever seem to compile right with it. confused.gif

Or I'll dig out the old Borland CBuilder. That was really sweet. Integrates with Delphi nicely too.
Best working set of tools I ever played with. biggrin.gif
Users WebsitePM
  Top
 

 
K^2  
Posted: Wednesday, Feb 3 2010, 15:58
Quote Post


Vidi Vici Veni
Group Icon
Group: Zaibatsu
Joined: Apr 14, 2004

us.gif

Member Award




I's not just a problem with wide characters. If it was, you'd get messages t h a t l o o k l i k e t h i s . Or worse, get cut off after first character, if you are going by \0 delimiters. Fact that you are getting '?' for all chars, says that output is garbage to begin with. It's not a matter of encoding.
PMMSN
  Top
 

 
ghost of delete key  
Posted: Thursday, Feb 4 2010, 07:28
Quote Post


ಠ_ಠ ... otter ...
Group Icon
Group: The Connection
Joined: Dec 27, 2003

gadsden.gif

Member Award




QUOTE (K^2 @ Feb 3 2010, 10:58)
I's not just a problem with wide characters. If it was, you'd get messages  t h a t  l o o k  l i k e  t h i s . Or worse, get cut off after first character, if you are going by \0 delimiters. Fact that you are getting '?' for all chars, says that output is garbage to begin with. It's not a matter of encoding.

SOLVED

Heh, this time you're off the mark, K^2.
Unbelieveable, but true. cry.gif The universe will implode now.
It's entirely a matter of encoding.

Of course the input is not garbage. It are the strings that Vice City spits out, and iidles original vcdbg.asi works just fine. This is his code.

It turns out to be what Gangsta Killa said.
I never had this problem using Borland, so it never occurred to me that MS has such an encoding option for projects. Maybe it does, and I never needed to worry about it.

So I dug around, and in 2 minutes found it.
Looky:

user posted image

VC++2010 sets the character encoding to Unicode by default.
So I set it to "Not Set", and that solved the problem.
The project compiled clean, and the asi hook works like a charm, sending all the properly legible strings to DebugView. biggrin.gif biggrin.gif biggrin.gif

C++ syntax still gives me massive migraines for some reason, so expect to see a lot more of me around this board. turn.gif

Thanks for the input guys, you saved me pulling out plenty of hair.


One question remains unanswered though...
even if the character encoding was Unicode, shouldn't the regular ANSI characters correspond to the same characters in Unicode?

I know very little about character encoding; I've not had to worry about it since things usually just "work". sigh.gif
Users WebsitePM
  Top
 

 
Andrew  
Posted: Thursday, Feb 4 2010, 08:39
Quote Post



Group Icon
Group: Forum Admins
Joined: Jul 21, 2003

Member Award




Heh glad you managed to solve it, I had no end of problems with the character set in visual studio.
PM
  Top
 

 
Haro  
Posted: Thursday, Feb 4 2010, 10:15
Quote Post


I reject your reality and substitute my own
Group Icon
Group: Members
Joined: Jun 1, 2006

au.gif

XXXXX



Perhaps you should all read this. A guy over at the GameDev forums asked a question about Unicode a few days ago, and someone posted that link. I had a read of it since i probably should learn a bit more about Unicode and character encoding, it's quite an interesting read.
PMMSN
  Top
 

 
ghost of delete key  
Posted: Thursday, Feb 4 2010, 10:42
Quote Post


ಠ_ಠ ... otter ...
Group Icon
Group: The Connection
Joined: Dec 27, 2003

gadsden.gif

Member Award




Thanks for the stab-in-the-dark fix, GK. icon14.gif

And thanks, Haro for that link.
QUOTE (Joel Spolsky)
Did you ever get an email from your friends in Bulgaria with the subject line "???? ?????? ??? ????"?

I got one from Vice City like that.
The Bulgarians must be taking over. Tommy better get busy. :


*****

One more unrelated Q:

Anybody got any good code snippets handy for reading resource strings?

I want to prepend certain lines with certain strings, and I want to store them .ini style so I can change them without recompiling a project.

I can do this easily in Delphi, but I don't want to port the project, and I need to get handy with C++. smile.gif
Users WebsitePM
  Top
 

 
Swoorup  
Posted: Saturday, Mar 17 2012, 12:52
Quote Post


innovator
Group Icon
Group: Members
Joined: Oct 28, 2008

au.gif

XXXXX



Bump!!
Does anyone have the source to vcdbg.asi.

This tool looks pretty handy. I just was running this with IDA and it would catch debug messages and output them in IDA message view.

Even if there is no source available, is there a way I could catch this debug strings?

EDIT: Solved. Source was available in the LC launcher source

This post has been edited by Swoorup on Friday, Mar 23 2012, 04:19
PMMSNYahoo
  Top
 

 

0 User(s) are reading this topic (0 Guests and 0 Anonymous Users)

0 Members:

Topic Options Reply to this topicStart new topicStart Poll
Search topic for posted by (exact match)



 
IMG IMG