Beta Technical Demonstration - Translation without Hexing the EXE
The attached links contain 1 executable (derived from Butchered 2b) and 3 DLLs, plus a folder containing 009.lng, which is a text file example which begins (with the help of the DLLs) to translate Butchered into English. (language code 009) The latest release also includes a script to switch between Release and Logging versions of the translation DLL.
If you are Brazilian or Spanish or German, your default system language code will not be 009, and you should create a new file for your language, this version of the EXE should only accept a language file which is default for your system, otherwise it will revert to the normal Korean text. -- Oh! And it only takes any notice of the primary language so it doesn't matter if it's British English, US or Canadian English, Australian English or English International... they are all 009. The same should apply to French French, Canadian French and South African French or Portuguese Portuguese or Brazilian Portuguese etc.
Extract all the files into a working client setup. Preferably a >= 197x one, but that's up to you.
Originally 2 of the three DLLs had an extra extension. Either '.rel' or '.dev'. You need to delete the extension from the end of one or the other of these.
In the current release the files are "IntStr[Release].dll" and "IntStr[Logging].dll", and the script "SetLogging.cmd" should allow you to chose which one to make active. (some reports that it doesn't present the question, I can't imagine why as the syntax is valid from DOS 5 [where the extension would have to be .bat not .cmd] to Win7)
The '.dev' or [Logging] version will slow the game down considerably, as any string based API is not only patched, but also the string and it's location in memory are logged to a file called "StringDbg.txt"... this is to help you locate the strings you want to patch into your own language.
The original log was really only Dev friendly, but the latest release produces a file which should import into spreadsheets easily and therefore allow you to remove duplicate lines and identify string address offsets easily.
I'm not using OOo because I don't have to pay for it, read why I am in the spoiler
Spoiler:
I paid for Office 97, 2000, 2003, but refuse to pay for Office XP (too many bugs) or 2007 (radical UI changes that would have made sense when we had the chance to get A4 Landscape screens, but is worse than what we had before now that everything has already gone Widescreen). Running Vista x64, Office 2007 is the "oldest" version my OS properly supports... so in that MS have failed me, and Oracle (Sun) won me over.
Last version of MS Excel I *really* used (2003) had something very similar, and so does Gnumeric, and Lotus 123, so I'm sure you can figure it out for whatever you use.
And how the file looks directly after importing into spreadsheet.
I've only translated a few strings in the 009.lng file, as I'm more concerned with getting the libraries working flawlessly and then getting an executable which uses them more cleanly. However, I don't expect the format of the .lng files to change much, so this is an opportunity for you guys to start building up and sharing some .lng files which you would like to have implemented.
Now... if you are using German or Spanish, or especially if you are trying for Chinese or Japanese, you will want to patch the code page passed to CreateFont() in the executable, before you do anything else. Ultimately I hope to implement a "fix" in the executable which will pass CreateFont() the default system codepage, but for now you will have to do this manually your self. (I wrote a guide to doing that a long, long time ago.)
Also, if you look at the log file you will see that this system not only shows where each string is located in memory when it is used, but also shows up many many strings which are never displayed. Firstly all the strings in the configuration files, 'hotuk.ini' and "ptreg.rgx" and such, but also the strings which represent the resource files, meshes, animations, textures and sounds. You may well want to customise these, and (with care) you can do so using this method, but if you do start working along those lines, please keep those changes clearly defined at one end or the other of your .lng file, and cut those changes before sharing it... that is likely to be a highly personal preference.
Through the discussions here, I will probably implement reading from a Global.lng file as well as your language, so changes for your server (regardless of the users language) can be made there.
Smart folks might like to comment on "how this system works" and continue to "suggest" alternatives... I'm still open to that, and working hard on trying out different ways of achieving the same thing. But as I say, I have not made any major change to the format of the .lng files in a couple of months, [strike]and feel that it is pretty much as standard as it can be[/strike]. I'm likely to implement fully sectioned Windows .ini or .inf style of .lng files in the near future to allow for colour and font face / style changes in displayed text, as well as altering locations and alignment.
I've implemented it as 2 DLLs (in the end, since you have a choice of slow developer logging IntStr.dll or fast(er) release IntStr.dll) because I wanted to have a high level language to rapidly develop reading the .lng file and parsing a list of addresses looking for a match and passing back a pointer to an alternative string, where the 'International.dll' is written in pure assembler, partly because, by reading the return address off the stack, it can see what code is looking for a certain string, and can modify the API call even more depending on where this API was called from, and partly because only by using assembler do I have the ability to take off only the arguments I'm interested in altering and then pushing them back on the stack in the correct order before directly calling the API.
Ultimately, I hope to make them one DLL all written in C(++). Right now, the high level language used to produce IntStr.dll (Both versions from the same source under conditional compilation) is written in freeBASIC, and that will certainly change to Visual C++ 6 - 9. (already started)
As the example 009.lng file states, don't worry about alignment of text and text overlap too much. I will fix that in International.dll as time goes on. Also, please don't worry about the messy way I'm importing these DLLs into the game... that will be changed once things settle down a bit. It's just a RAD shortcut, but it has meant changing the OEP of the main executable, and disabling the 'write' protection on the .rdata section of the PE. (I'm sure you know me well enough to know I won't allow that to remain the case for long.) I will ultimately link the DLL and it's APIs into a new Import table which will completely replace the one in .rdata.
Other than that, all feedback is welcome. Once the port to C++ is complete (which will only happen once the complete feature set and .lng file format is set in stone) I will open the source to you so you can implement any encryption, signing or compression you think is important to you.
So far, although I can see a couple of "risks" with this method, (user skinning etc. which they do anyway) I can also see it saving an awful lot of people a heck of a lot of time and effort.
File Scanned by Virus Total for your safety. Please confirm MD5 checksums etc of the file you receive against those VT list.
And here's the original links:- SendSpace MediaFire
Let me know if you need others. :wink:
--- EDIT ---
When the links died I attached a backup from 18th Dec 2010. But I attached to the wrong post. :doh: Attachment 96768
28-11-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
very nice!
---------- Post added at 11:15 AM ---------- Previous post was at 10:15 AM ----------
One question. How can I translate that strings that appear together with the Tribe, Level, Charname in the login screen?
String @6053916 = '%s' not replaced.
String @1309792 = '템스크론' not replaced.
I Belive this one is the one for the Class, But Idk how to proceed.
---------- Post added at 12:05 PM ---------- Previous post was at 11:15 AM ----------
String @6091092 = '%d' not replaced.
String @1309792 = '73' not replaced.
String @53923952 = 'aaaaaaaaa' not replaced.
String @6053916 = '%s' not replaced.
String @1309792 = '템스크론' not replaced.
String @6053916 = '%s' not replaced.
String @1309792 = '파이터' not replaced.
aaaaaaaaa = my char
73 - his level
28-11-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Thread teleported from Priston Tale Releases to main page O.o
Are you going to develop this? This is actually cool idea, from translation through item table and ending on PT GUI/SKIN language selector :)
28-11-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Yes, I'd like to keep this going, its very easy than hexing. And faster. I think bob should develop some kind of encription, it could be XOR Key based, otherwise, players could easily mess up with the texts.
29-11-10
bobsobol
1 Attachment(s)
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Thanks for the recent input guys.
It's not in release as I'm working in ways which are quick to develop and easy to change, but not good for a release... I wanted peoples input, especially people who want Br or Vn type translations... or even Fr, De, Es, No etc. which don't normally come to PT.
If (l)users want to skin their PT so that it's full of rude words or all in l33t5P34k, I don't think they gain any advantage in that from the server's point of view.
If item and level tables where handled as well, there would have to be some method of "signing" the files with a private key, that much is for sure.
Spoiler:
An example would be the GLUEXML.TOC file in one of the WoW Interface.MPQ archive which is signed with GLUEXML.TOC.SIG and ensures you don't change the XML to alter the layout or URL for the login screen.
Nobody has broken that .SIG file (yet) that I know of.
Lelejau asked earlier about '%s' there is no point in replacing... I've said before that that is stupid code where they char* pointer = wsprintf('%s', szptrRealString); TextOut(pointer); When they should just TextOut(szptrRealString);
The problem with 1309792 = '템스크론' and 1309792 = '파이터' is that they seem to be in the same location... fact is they are transferred there with a memcpy() instead of a strcpy(). (difference is "character" datatype copy or "byte" datatype copy)
I'm not sure if I should patch memcpy() as well, or just replace the memcpy() instructions in the game with strcpy() calls.
memcpy() doesn't check for null characters (end of string) and stuff, so it's a bit faster. strcpy() can cope with strings of any length.
I think I should find a way to patch TextOut() APIs to allow custom text location adjustments for different languages. (centre stuff up, align it and as on)
29-11-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
So, you think you can handle it bob?
30-11-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I can... I could use some feedback from people, such as you've given here.
Different people will want different translations, and it takes a lot of in-game testing to find how all the strings appear in the debug log (or, don't appear in any unique way).
If there are too many of them, patching memcpy() would probably be good, if only a few (like the login screen) modify the exe to use strcpy() instead of memcpy(). But I need play-testers and translators to give a quantitative assessment.
I also needed to know I wasn't just doing this for my-self. It's not worth the effort if it's only me that's ever going to use it. I don't run an open server, I just develop. So there's no point me developing something nobody will use.
Once we have translation files for different languages, and can prove the API patches work, I can replace the import table completely and lock down the memory sections I unsecured to make development quicker. Replaced import tables means I don't need code to modify API vectors, so no slow down, and no need to remove Write Protection in the import table, so no risk of overwriting constants etc.
When I'm happy I'm not prototyping any more, but producing a practical final release implementation, the slow down that Vormav is concerned about should be minimal... and I can already see speed gains that can be achieved at the same time, as well a memory requirement saves to counter the extra load placed by the DLL(s) and their temporary data. (you don't need to keep the Korean strings to fall back on etc)
In short, once I have enough test data from people developing different languages, and can be sure that the solution doesn't need any more tweaking to fit different scenarios, I can re-implement the design as if it where always a part of the client.
I think TextOut() should be patched too, with offsets against the original location... that will help the Chat Overlap problem in different languages. You can also use TextOut() with centred text for "Connecting to server", "Connection failed" etc. but I'd have to store another, fast access lookup table for such changes and decide how to store those details. + / - X and Y in pixels... probably, applying different justification? Not sure.
Something like a [Positioning] section with Address = x, y, j where j = "l", "r" or "c" maybe? Or maybe AddressX = int, AddressY = int, AddressJ = char. That would make a bigger translation file, which would require less logic in the dll to store the info in an array or linked list.
So there is still design considerations... and actual input from admins and other devs would be much appreciated on such issues.
01-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I guess I am doing thing you are doing right now but in different way (much simpler).
Would it not be better to add ENCODING and FONT to translation file:
ISO 8859-1 Western Europe
ISO 8859-8 Hebrew
etc.
and font ARIAL, Tahoma etc.
So code can patch this and translation will be added with right encoding and font.
Anyway some stable method need to be created so people will start porting this into they servers.
01-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I could test it. I want to use. I did something like that in Delphi, using api hook, hooking the TextOut() function. It was OK, but some messages, like the welcome message was very weird....
Something like this happened:
The right:
"Welcome to MyPT.
The boostime is x:14."
With my dll:
"Welcome do MyPT (a werid character here ) The bosstime is x:14.
The bosstime is x:14."
So I stopped with it. I want to try your method. What kind of feedback do you need? I already gave you one. If you can fix that, and release it here, so there, I can start again with it and give you more feedback.
01-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
@Vormav: Yes... absolutely. I had already considered that the language .ini files should have font encoding details, but I have demonstrated how to do that in Olly, so if people need a specific codepage to start making translations, they can do that.
I also missed replying to one of your earlier comments
Quote:
This is actually cool idea, from translation through item table and ending on PT GUI/SKIN language selector :)
Yes, the strings for the location of TGA and BMP files come up in the debug versions log, and you can actually point different languages to different folders with those strings... it's not easy to do it for just 1 or 2 files though, and usually means you need to keep 2 folders full of every texture in them if you want to support 2 languages with appropriately "skinned" GUI. XD
Most useful... it can point to different folders for .sin files. Very important for multi-lingual client.
@lelejau: That's great! Actually, the best feedback I could have is if people would try adding as many translations to their own .ini files as possible, and comment out ones (like Clan, Tribe, Skill etc) which are problematic.. and also comment what issues they present if you try them that way.
This is why I included commented out "bad examples" and commented "better" or "good" examples of how to use it. So you can see how you can comment things you'd like to achieve, or would like better implemented.
Also, listing the Debug versions log lines of strings you'd like to replace but are finding problematic.
This gives a quantitative assessment of where issues lie, and gives me an idea what I need prioritise on, and what bias I should place on optimisation... do I keep size low, or number of patches low, or intrusion low... all these things are a matter of "balance".
@all: I'll say again, I didn't put this in the release section because it's a development idea that I've proven can be worked, but haven't completed.
I'm still designing this development... the implementation isn't what I want to release, but it's the quickest way for me to test and prove theories.
If I was working as my Tutors taught me, I'd have a program design before I began... but we all know PT development can't happen like that. I can whip up prototypes like this, prove they work and refine them to the point where I have a design, and then implement it properly.
That proper implementation will be released with source code... I hope the source will be in C. This release has 1 Assembler DLL, and one Basic (freeBasic) DLL, but I have a folder which builds in MS Visual C++ with project files for versions 6 - 9 inclusive. (VC6, VC .Net 2003, VC 2005 & VC 2008)
This should allow each private server to implement extra securities, signing, compression, encryption etc to their own tastes. While still having a common base which we will all understand when new server devs come here asking questions about it... as they do about QFs idea of putting the IP in the executable, and many of us hide, encrypt, move, compare or do other things to that IP for our own server.
I really hope this is clear. What I've done and released is for speed of, and for feedback for the design. It does slow the client down (because it's a prototype full of beta debug info and dynamic patches that wouldn't be necessary in a fixed final release), it isn't secure to release to players (sometimes it memory leaks, and players could easily put ridiculously long strings where very short ones should be) it's not at all complete or how a final version should be... it's just a proof of concept, that needs your input to get a final design and proper release.
Thank you, especially to those who have posted their ideas and desires here.
01-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Thank you, to show all you are capable of again. And good luck in this project. I think we're all anxious for it, at least I am.
I want to help as I can. feedbacking etc.
02-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
This is great project but I am concern about SPEED.
With few records it is OK but what will happen when you will patch 200+ records?
It would not be faster if you put that file in memory and than "push" new translation offsets there?
One file that translate inventory, .sin files, messages and many other things would be awesome! GL!
02-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
But if you do that, all about this project translating without hexing de EXE would be invalidated, dont you think?
I cant see any slow down in my client, only when I use the dll to write the strings into the exe.
And BOB, another ideia, to put in the txt is this:
We can see alot of the same string. Example:
[quote]
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @6186476 = '|' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @6186476 = '|' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
String @1309984 = 'Ver: 1.99.7' not replaced.
String @53940384 = '' not replaced.
String @6102924 = '/도우미' not replaced.
String @6191640 = '%s%d.%d.%d' replaced with 'Ver: 1.99.7'
[/code]
It would me easier if it checks:
Code:
If Exists(string) Then
do not write in txt
Else
WriteTXT(string)
End If
:P
02-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Quote:
Originally Posted by Vormav
This is great project but I am concern about SPEED.
With few records it is OK but what will happen when you will patch 200+ records?
It would not be faster if you put that file in memory and than "push" new translation offsets there?
One file that translate inventory, .sin files, messages and many other things would be awesome! GL!
Ahh... this is the failing of not showing the source code. What you suggest I do to Speed it up, is what I it does do already.
The number of patches (or active lines in the ini / lng file) is not a big problem. I'm iterating an array of DWords looking for a match... yes, the more DWords the longer it will take to get to the end of the array if a match isn't found, but it's not a big thing, compared to the time it takes to render the text on screen.
No code is patched, except the existing APIs overridden, and it's not like I'm even looking at the strings until I can find an address match.
Right now the array isn't sorted... so you can put the most frequent string patches near the front, and they will operate the fastest.
Basic (the language) dynamic arrays are not the most efficient of memory usage algorithms but they are very easy to program... that's why speed is not great at this point. A C++ linked list should be faster, I can optimise in assembler if the compiler produces crap code which I can't easily do in Basic and would be better off writing 100% pure assembler if it weren't for the availability of C, which is often half way between Assembler and languages like Basic, Fortran, Perl, Ruby etc.
Other than that, I could also write a custom memory storage class in C++... break the list into ranges of patches so I have lots of small arrays / linked lists. If I use a pure static array, then everything is very fast, but will also take up an heck of a lot of memory when the game is running and mean I need a fixed maximum length of string... so I want to avoid that.
Needless to say... this method is faster than the MUI method Microsoft recommends now, or the "strings" resources that they used to recommend, by a long long way, and for many reasons.
Quote:
Originally Posted by lelejau
But if you do that, all about this project translating without hexing de EXE would be invalidated, dont you think?
Nope... because the .lng file may have options added, but I don't plan on taking them away... even if small changes are made, it would still be only a matter of Search & Replace to update your .lng to a new format.
What is "in flux" is not interception point, but how it's intercepted, what is intercepted (to I catch TextOut() and memcpy() too?) and extra features. (like the font creation routines)
Quote:
Originally Posted by lelejau
I cant see any slow down in my client, only when I use the dll to write the strings into the exe.
I agree... if I'm not using the debug logging version I see little slow down... but Vormav is correct that any string address not listed in the language file will be slowed by checking it against every possibility in the array, and when the array has more than 16K patches that will be quite some time difference. Less than 4K patches... not so much.
Quote:
Originally Posted by lelejau
And BOB, another ideia, to put in the txt is this:
We can see alot of the same string. Example:
It would me easier if it checks:
Code:
If Exists(string) Then
do not write in txt
Else
WriteTXT(string)
End If
:P
It would make it much harder and slower, for the exact reason Vormav has pointed out. That will create a very large array that has to be checked, written and rechecked each time a string is processed. It actually takes less time to just write it out to the log.
If I do DebugPrint() instead of file write, that is faster (I know, I tried) but that requires that people have tools and know how to handle the, normally invisible, Debug stream from a program... and PT 1977 creates DebugPrint logs anyway, so it would also have those logs jumbled up in it.
In case you're not quite with me as to why your method would be so much slower. You are requiring that I keep a separate array of addresses that have already had their action logged, which should be parsed each time a potential log entry might be made. That array will get really big, really quickly, and will have to be checked for each log line.
The simple solution to the long and repetitive log list is to load it in your spreadsheet, sort it (either on address or on string) and tell the spreadsheet to remove duplicate rows during analysis. I hope the problem isn't that the file becomes so big that it fills your hard drive... these devices usually have pretty high capacity and are reasonably inexpensive... still, it's just text, and for a little overhead, you can create the file with NTFS compression if that is an issue. (I suspect it isn't) Repetitive text information compresses very very well, even with the simplest of compression techniques. (Okay, RLE is probably too simple, but Squeeze, Deflate or LZH are all excellent... I believe NTFS Compressed files are LZ or LZ0 which is ideal and the reason it was implemented, to allow big logs on NT servers not to take up lots of disk space)
02-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Quote:
Originally Posted by bobsobol
It would make it much harder and slower, for the exact reason Vormav has pointed out. That will create a very large array that has to be checked, written and rechecked each time a string is processed. It actually takes less time to just write it out to the log.
Yes, I didn't think about that. But no problem. :) Bob, when do you think you can release a second version to us? I really want to try out and give you more feedback.
03-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Okay... I'll go back to features in the prototype and cease working on the stable C++ thing for a bit.
Make some variations to see what you guys like, or find works nicest. Get some font and codepage choice in there and some TextOut() repositioning, stuff like that. And maybe implement some memcpy() patching, to see what it picks up. Big worry with doing it globally is that memcpy() isn't designed for strings of text... it's designed for any and all arbitrary data. I know it's used for moving textures and stuff around in memory in PT for example... so you could get some *VERY* strange entries in the log from that.
Working without a design, you never quite know when the breakthrough is going to happen, so putting a time scale on it would be hard, but I'll get working and we'll see how long it takes. I'll let you know how it's going too... but please don't be afraid to keep trying to add patches to your .lng file and letting me know which work and which don't.
03-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
If you could just share the version that you said you have fixed that Tribe and Class stuff, I could start to patch again and say to you what is working and what is not.
03-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I don't have such an implementation yet. I said I know what it needs, but don't know the best way to implement. Fix the Exe, or add another patch to the DLL.
To make it work, I replaced the memcpy() call with a strcpy() call... but that has to be done right throughout the game exe in any place where strings are treated as just binary data. A global patch to memcpy() will produce logs of all pictures and figures and vectors and anything else that gets memcpy()d.
I also said I will make a couple of implementations and let you guys decide which you prefer. Either option is not very nice. Patch the exe makes it hard for people to use the DLLs with other game.exe, patch the DLL and you are looking at *MAJOR* intrusion into basic functionality of file and memory management in the game, and likely a massive slow down.
Maybe that could be minimised by setting ranges to not be compared to the array, IDK.
03-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Fix in the dll, its easier.
03-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Aha... new info on Tribe and Class.
It's not MemCpy, it's a const chr * "%s" used in wsprintf("%s",lpszTemp) or wsprintf("%s",lpszMori)... so it is possible to implement in the existing function patches.
Why they don't just wsprintf(lpszTemp) or wsprintf(lpszMori) IDK... I can't think of any instance where that would be a "good programming technique"... but when did that ever stop Triglow? :wink:
Could do with a routine to "count C formaters" (ie, any % that isn't followed by a %) and I remember (and still have a copy of) an attempt at doing this. Picking out which ones are strings and what is not is... err, not hard, but complex enough to be a considerable slow down.
Then run the string replacement check on each of the follow-up parameters... at least, if they are filling a %s formatter.
If I write a routine to just give the number of extended parameters, and another to say if Parameter(x) is a string or not, that should simplify the design sufficiently enough to reduce the slow down when ever possible. I'll work on that now.
04-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
OK bob, ultil you dont release, I'll patch what I can. Any news, I'll post here.
---------- Post added at 11:48 PM ---------- Previous post was at 10:29 PM ----------
Another feedback.
In KPT 1986, when I got DC'd because of the checksum, this string appears:
Quote:
서버와의 연결이 끊어 졌습니다
It appears in somekind of MessageBox and in the chat.
In the debug txt I found:
String @1239352 = '서버와의 연결이 끊어 졌습니다' not replaced.
But bob said we should patch those kind of "numbers". So, I looked a lil' bit and found this:
String @54439880 = '서버와의 연결이 끊어 졌습니다' not replaced.
And then, patched.
54439880 = "Desconectado do Servidor"
But, this string is only beeing patched in the CHAT. Where it should be patched both in chat and in that kind of messagebox.
---------- Post added at 11:53 PM ---------- Previous post was at 11:48 PM ----------
And bob, that tribe and class thing, will probably happen with the Mechanician Spec showed in the item.
04-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
That would suggest that the string is either copied in the opposite direction (so patch 1239352 instead) or they are using two constants that have the same content... f.e. See how many times you can find a sequence "/0%s/0" Those are all string constants, and they all have the same value. Also see how many "/0템스크론/0" (Tempeskron) there are... I found 5 in RData. That's shame on the Compiler optimisation routines, it should merge identical string constants, and clearly isn't. They may have it configured wrong in the project / make file, so I can't completely blame MSVC 7. I have to admit that I tend to manually "merge" such constants in a .h file, so I can change them globally in the file without a whole heap of Search and Replace work. But constants which are stored in "scoped" variables can't be merged automatically, so where I can force the merging by specifying it my self, they can also by-pass it's ability to optimise by writing the code badly. (There are some reasons why this might be advantageous, and therefore not bad, but not many.)
I've implemented code to do the job on the missing %s parameters, but my implementation is (through my miscalculation) corrupting the stack frame. Implementing full frame isolation seems excessive to me so I need to think up a way to create a small, lightweight temporary stack. I'll probably just declare some static memory and use that, but I need to "step away from the tree and see the forest" again, for a bit. :wink:
06-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
It would be nice, an option like this:
111 = "My Text"
Color(111,(255,255,255))
hehehehehehe.
I'm doing some progress, so far I have this:
Quote:
;Frases da tela inicial.
6209776 = "Ver: 1.98.7"
6215984 = "Conectando ao EvoPT..."
6215956 = "Falha na conexão!"
6215928 = "Preencha com seus dados!"
6215900 = "Usuário ou senha incorretos!"
6214708 = "Deseja continuar?"
6215808 = "Conta já está logada!"
6215720 = "Tempo de jogar expirou."
6137004 = "Pod. de Ataque:/n"
6136992 = "Vel. da Arma:/n"
6136968 = "Crítico: /n"
6136944 = "Taxa de Atq: /n"
6136920 = "Bloqueio: /n"
In KPT 1986.
I'm just waiting bob to release an updated version.
06-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Changing text colour is kinda beyond the scope. TextOut() and DrawText() APIs do not take colour as a parameter, but simply use the present GDI Pen. So there is no connection between the contents of a string and changing of default colour for subsequent GDI operations. That is by far better handled by modifying the game.exe I think. (Though you could patch CreatePen to a DLL function, and change the parameters passed based upon the return address. I just don't think it's practical.)
Preserving an unknown quantity of stack space and still passing parameters on the stack to a new API is doing my head in. >.< I've tried a number of approaches and they are getting silly complex and I'm still hitting the high level code causing fatal exceptions because it's reading memory it has no right to, unless the low level code completely destroys the information on the stack we're trying to process.
06-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Oh, I thought it was possible to do.. But, what about the SetTextColor?
07-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I think you are correct. The API is SetTextColor() not CreatePen(). The rest applies however.
Thinking about it while trying not to have a brain explosion on stack frame corruption and infinite possible parameters, I also considered that we could include (as you say) SetTextColor to any TextOut() or DrawText() API call... especially if we are patching the string pointed to anyway.
So I'll add that to a To-Do list. :wink:
Just checked MSDN and both recieve the hDC that SetTextColor() would require... but you list 4 byte figure, and although SetTextColor() takes 32-bit DWord the first byte must always be 0. (0x00bbggrr)
I assume you where hoping for an alpha level, which is not supported by either of these APIs (TextOut() or DrawText()) and would require you create a new Device Context, and blit that hDC to the main display hDC with a separate Alpha level, and that tends to destroy anti-aliasing (if any is enabled in the system), unless that is used as a mask... this all becomes very complex and is going to cause a major slow down. I doubt anyone will think it's worth it just to have "ghosted" text. XD
Outlines, highlights and / or shadow may well be much easier to achieve by simply displaying the text with a different colour at 1x1 pixel offsets from the main text. That would make for a pleasant effect IMHO, but the game does this in some places already, and you'd have to be careful not to "double do it". XD
Please comment if you think otherwise.
07-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
If you are saying, coloring text would cause a slown down, who am I to disagree :)
But, yes ofc, an option like:
111111 = "My Text",1,1 ; String,bold,underline
Would be nice ofc, JUST if it DOESNT slow down the game very much.
07-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
RGB colour, via SetTextColor() is not too hard. Bold, Italic, Underline is all set in the CreateFont() API and I believe that the program then uses SelectObject() to specify which font to use during each TextOut() function.
Again, that could be added, and I could set aside space in the DLL for say 16 different faces. Then specify a font face, and a color to associate with each address... but they will only be applied to the display of text at that address, so TextOut or DrawText captures, not any of the strings that are only caught in string manipulation. strcat, wsprintf etc. You may have noticed most strings are placed in a buffer at the same 5 or 6 addresses before being passed to these routines, so even 16 fonts / font variations would seem excessive.
It's the "Alpha" or "Transparency" that I think would really kill the frame rate.
Unless by
Quote:
111 = "My Text"
Color(111,(255,255,255))
the "111" in "Color" is supposed to refer to the string address, rather than the opacity (transparency, or alpha blend).
I wouldn't do it like that anyway. I would follow MS ini/inf standards and have:-
Code:
[Strings]
;Frases da tela inicial.
6209776 = "Ver: 1.98.7"
6215984 = "Conectando ao EvoPT..."
6215956 = "Falha na conexão!"
6215928 = "Preencha com seus dados!"
6215900 = "Usuário ou senha incorretos!"
6214708 = "Deseja continuar?"
6215808 = "Conta já está logada!"
6215720 = "Tempo de jogar expirou."
Oh, if the number to colour conversion seems a little odd, I could implement "= #FFFFFF" being equal to "= 16777215" with only a little overhead in loading time... that's the delay before the splash screen arrives... and as more strings are added, I'm considering displaying a splash or loading bar during that routine anyway... it's currently quite tempting to click the icon again because you think "Nothing's happening." XD Actually, it is, this is the point where I'm looking up and reading all the settings in your .lng file into the memory arrays for rapid processing during game play.
B.T.W. what is the file name of your Brazilian Portuguese .lng file? I know English is "009" regardless of whether it's British or American (or Australian, Canadian, New Zealand, or International English)... so I'm hoping that Brazilian Portuguese will have the same number as Portuguese Portuguese and, most importantly, not the same "009" that we have for English.
07-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Just awesome! This ini you showed me, is only ficticial or is it already working? I mean,adding just
Quote:
Originally Posted by bobsobol
[Colors]
6209776 = 16777215 ; White
Wouldnt be possible without slowing down the exe, right?
About the Font, I already have in my DLL written in pascal, a routine to adjust the Font Call, CreateWindow, ShowWindow and some others API, so to me it wouldn't make a big difference.
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Just one thing, the TextOut API, gets the X,Y and Z(?) of the string to show. I mean, in my dll written in delphi, I could put the string a liltle bit more to left, right, up , down....
It could be useful in this txt so we can align the translated strings, or do you think it would slow down the game?
08-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Answers, in order:-
Q: The INI file is fictional?
A: Yes.
Q: It would slow the game down?
A: Those things? Not much.
Q: I already have in my DLL written in pascal, so to me it wouldn't make a big difference.
A: It might... because it would support using different fonts and different font styles in different places without making any modification to your executable. So Character name could use one font, Tribe another and Class another... not to mention Speech bubbles, Tooltips, Quests and Chat window.
Q: TextOut API, gets the X,Y and Z(?)
A: No, TextOut() only takes X and Y values, however it passes it's work on to DrawText(), which also allows for Alignment and wrapping to fit within a RECT structure. If I take over TextOut() API functions and implement different alignment and RECT structures, based upon the strings location in memory and offset from the values presented in by the main game.exe, we can leverage a lot more control over text placement as well as colour and style, at very little cost. (Remember, TextOut() system API works stuff out and then calls DrawText() "downstream" anyway, so we just do that our self and gain more control)
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
New libraries! I finally got my head around the stack issues... address the stack indirectly and don't mess with the frames. XD
--- EDIT --- !!! Warning !!!
This upload has a bad build of the Release library, I pushed it out too quick with too little testing.
If you already have this download, patch the IntStr[Release].dll with the one from my next post.
If not get the latest version from my first post in this thread, which is kept up-to-date.
---/EDIT --- MegaUpload DepositFiles Hotfile zShare Uploading
or All these links thanks to Multiupload. Virus Total analysis of this file with many Anti-Virus. (in case anyone is concerned)
Place these in your game client folder. Please submit any .lng files based on the provided executable (this version now has the "rain" patch), or another based on KPT 1977 only... offsets will be meaningless to others if not, and that is not very "sharing". (then again, if you want us to do some work our selves, I guess that's a good way to go)
Additionally, please run the "SetLogging" script at least once. You can now execute this any time you want to enable the logging of captured strings (makes the game really slow, but is the best way to find offsets) or disable it, returning the game to normal running speed. (mostly)
I've not changed the format of the .lng file so far, despite the new strings with can be captured... but I have changed the log format... this is now very easy to import into a spreadsheet as a CSV (ignore the first two lines) and sort by address / string / api or remove duplicate lines all automated by the power of your spreadsheet program. I hope this makes things easier for people to find.
Enjoy, and please report back your findings... I'm now going to work on colours and fonts and positioning and things.
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Thanks bob. I'll try this.
I think I have a problem, the cmd file, when I open it, it just close in the same time...
08-12-10
bobsobol
1 Attachment(s)
Re: Beta Technical Demonstration - Translation without Hexing the EXE
The problem I'm having is that the new Release version (non-logging) is not patching any strings. :s Odd.
--- EDIT ---
Oh... I see! It's a misplaced meta-directive in the source that's skipping an "Else" in the non-debugging build option. IDK why it compiled without error like that. :s
Please use attached alternate InStr[Release].dll instead. (If you didn't get the update in my last post, then get it directly from OP, which I've updated to include this fixed [Release] library.)
---/EDIT ---
The script just deletes IntStr.dll and asks if you want logging enabled or disabled, then copies either IntStr[Logging].dll or IntStr[Release].dll to IntStr.dll depending on your choice.
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
my game.exe is crashing in the select char screen bob...
*When I'm using the IntStr to debug, my game crashes in the char screen.*
Well, when I use the older version, everything goes fine, but with the new version, it always crashes in the select char screen.
Resuming, I cant use the new version. :(
08-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I have had intermitant crashing even with the old version... fatal exception usually after connecting to the server, and before character selection appears.
Still happens now... but not all the time, and exactly which API causes it is different every time I run it under the Debugger... wait half an hour and it stops happening.
So I presume it's to do with memory fragmentation, the same as the server crash after 20hrs or so, and also presume that it will go away when the whole lot is ported to Visual C++.
I can't track down what it is, because there is no guarantee that it will even happen when I'm tracing. Sometimes it does, sometimes it doesn't. *shrugs*
If the problem is persistent, and consistent on your setup, perhaps you can figure out where it is happening. As I say, for me, it happens, but at different points in the code each time it happens, and it doesn't usually happen, just sometimes it does.
When it does it happens and happens and happens and I think I've changed something and I go back to older builds and it still happens and I go away, play a different game or run a different game executable or watch some TV and come back and it's fixed it's self, without explanation.
I don't know how to debug a problem that presents with a different cause but the same effect every time it happens, and doesn't always happen even when given exactly the same circumstances. I've stack traced, and found it reading or writing to memory that hasn't been allocated in aton in WS2_32 and in wsprintf from kernel32 (not my one) and in game.exe and in many other APIs, all using different non-existent memory, and never the same one twice.
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I think I've added correctly, because the older version works perfectly... Are you sure this isnt to do with the dll?
08-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Well... I really can't say, because the original version I posted did it to me, and this new version doesn't do it any worse.
It happened then, and it happens now. And like a watched pot, it only ever happens when I'm not looking at it. XD
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Well, I'll try it again, and again....
If it isnt ask too much, could you share the sources of the first version?
I'd like to translate it to delphi.
---------- Post added at 07:08 PM ---------- Previous post was at 06:57 PM ----------
--- EDIT ---
In English "This application has encountered a problem and was shut down to protect your system." then "Would you like to report the problem to Microsoft?" who will completely ignore it. XD
Sounds about right, I have run-time debugging on and error reporting off, so I know that it performs an illegal memory access from different instructions and different locations in the code, upon different illegal memory addresses. All different every time, but always at about the same place. (connecting to server and getting character details for an account)
Almost as if it's getting something from the server at login which is beyond it's capability to deal with properly.
Porting to Pascal may be as effective as porting to C++, as I suspect the random nature of it is down to the memory management in the runtime library for freeBasic, which is solid on it's own, but is being mixed with VCs runtimes... they may not "play nice". I've seen VC get equally shirty about DLLs compiled with GCC, and then you compile the main exe with GCC and everything is fine and dandy... Oh! And even more so with a VC executable using a Borland C++ Builder DLL.
08-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Thanks bob. And, just for logging, the crash is also happening with the new client and new dlls you've posted.
I dont understand the sources, is it VB6?
@edit
The exception, in the first SS I showed, occurs in this offset:
168B71AA
08-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
That offset is nonsensical, that's why it's illegal.
No it's not VB6, I believe I stated quite clearly that it is freeBASIC, which builds to GAS source against MSVCRT.dll which it assembles with GNU GCC from the MinGW (hence the MSVCRT dependence) and links with GoLink to the fbrt.bin library. :wink:
freeBASIC is like QBasic only with more ability to ObjectOrient than VB6, and less enforcement on OOp than VB.net. And you can in-line assemble like BlitzBasic.
It's similar to the way ObjectPascal is a bit like Delphi and a bit like GNU Pascal and also kinda like neither of them. :lol:
All taken with logging enabled.
To evidence this logging, this is a fragment taken during Character Selection:-
Code:
wsprintf(), 6091092, "%d", "/* Not Replaced */"
TextOutA(), 1571880, "91", "/* Not Replaced */"
TextOutA(), 53925752, "noobie", "/* Not Replaced */"
wsprintf(), 6194412, "템스크론", "Tempeskron"
wsprintf(), 6053916, "%s", "/* Not Replaced */"
TextOutA(), 1571880, "Tempeskron", "/* Not Replaced */"
wsprintf(), 6067616, "파이터", "Fighter"
wsprintf(), 6053916, "%s", "/* Not Replaced */"
TextOutA(), 1571880, "Fighter", "/* Not Replaced */"
And, to be clear, I don't doubt the difficulty you are experiencing, and have (intermittently) experienced it my self. But there isn't a lot I can do with it as I can't reliably reproduce this issue at will to discern what is causing it... and even when I do "catch" it in the debugger, it always seems to originate from a different source... all the details are changed from the last time I saw it.
If the address you mention is consistent, I'd love to know what code thinks there is something at that address, or if (as is indeed possible) there actually is some allocation to this process at that location on your system... because there is certainly nothing at so high an address when ever I run the game.
As to reading the source, it's very similar in dialect to classic ASP, but if particular points are confusing to you I'll happily attempt a translation of sections. It's unfortunate that Visual C++ is the most widely known and available development platform on Windows, because I could easily port this code to BCB using the VCL (which it shares with Delphi) but the conversion is much harder when restricted to ATL and MFC frameworks. Even I have to admit that the .Net framework would be preferable in this instance, but MSIL is no use to PT. XD
09-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Bob, even with this executable of yours, I cant run the game. With this exe, I cant even see the login page, the game just disappear after the last loading bmp fades away...
And no, the crash offset changes all the time...
I could select the char to patch the Morion and Mage, but the game is still crashing.
I think I could try to use this new version only to patch the Tribe & Class stuff...
---------- Post added at 11:21 PM ---------- Previous post was at 11:05 PM ----------
This is the third time I got this error. And, this offset is constant.
---------- Post added at 11:32 PM ---------- Previous post was at 11:26 PM ----------
BOB, I JUST CANT BELIVE.
I had one char called ¹Ba¹
I already had 5 chars, and I was lazy to delet one, then I created anohter account.
BINGO!
Your dll appears not to support special characters!!! Its working now!
Well, after all these annoying messages, I have another feedback for you!
=D
09-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Well, it's clear that you are running some form of XP, while I'm running in Vista x64.
For me, the issue is no different with either the new (rain enabled) translated exe, or the old one based on Butchered2b. And when one of them is playing up, the other does too.
It would be nice to get a feel from other people... maybe there is more of a problem on different OS, or maybe it's literally a memory thing. I have 3Gb installed, and obviously an x64 OS manages memory very differently for an x86 application than an x86 application, because it's creating a virtual 32-bit address space for that app to run in.
I usually find opening a very, very large text file, or playing back a video does... "something" (IDK what) that forces the OS to clean up and make it work, but so long as I keep trying to play PT, it will keep crashing, and always has. As I say, I put it down to the RTL for freeBASIC (or GCC, which ever way you want to look at it) not getting along with the RTL in VC. So it acts like "garbage collection" doesn't happen at the right time.
Of course the two compilers have a very different approach to memory management and garbage collection. But VC 7 has quite a different approach to VC 6, let alone going from null terminated strings to Basic strings in an array dynamically allocated on the heap. C programmers find this method very messy, but it's a lot quicker than messing about with mallocs all the time, and doesn't hit the OS so hard... at least not when you are doing it as often as this program does.
From a C / Assembler perspective, I would be looking to get an idea of how much memory to allocate before I start, and then malloc it all at once. The ATL and MFC just don't care about CPU usage and hitting the OS with complex and time costly operations and will malloc every time you instantiate a new object. So linked lists (which is the best C++ approach to a dynamic array) will be slow. The VCL works with the Heap the same as Basic and Pascal... because VCL was written in Pascal and only linked to C++ in BCB. And I believe the MSIL VM performs some kind of ranged allocation, dynamically mallocing bits of memory which it uses like Basic or Pascal allocate from a memory heap, but I've not seen clear documentation. (Maybe the Mono guys know, but I don't)
I've read that freeBASIC actually does call mallocs for new heap space, and that they worked hard to achieve good performance with this method. I've also heard that ObjectPascal uses malloc much more than traditional Pascal, and this leads to more stable and compliant LCL implementations than their equivalent VCL ones, and that's largely what the JCL did for Delphi and BCB too.
In any case... my options for ensuring it goes away completely seem (to me) to clearly be that I write either in pure Assembler (taking everything into my own control) or in Visual C++, so that it's using the same system as PT was written with.
My current (very incomplete) implementation is working on the assumption that an ATL string list object should be the way I should allocate the memory dynamically. But maybe some VC Guru out there knows better. If I went for pure assembler, I would run a two pass system, work out the total space requirement for every string in the .lng file and malloc that, then read the file again and fill in the memory allocated, and that method could be implemented in C / C++ too, but that's a waste of a high level programming language... surely? XD
Seriously though, if anyone has any better ideas on how to manage this issue, in any language / compiler / assembler I'm open to ideas. And your experience with this "bug", the frequency with which it occurs and the type of system you are running would all be good information to know.
I'll say again, freeBASIC just let me "throw it together" quickly for prototyping, Assembler simply let me ensure that what comes out of my APIs is exactly the same as what comes out of the regular OS ones, in terms of registers and stack state and so on. (It doesn't ensure that memory doesn't get fragmented to hell and back, or that I'm not going to allocate somewhere that game.exe thinks it has a right too... which it does, whether it's actually expressed that to the OS or not... we all know it's not very friendly XD)
Ultimately, I need a smaller RTL than the freeBASIC one, and I need to be able to write in a single high level language that everyone can use (which pretty much comes back to C++, and counts out using the VCL in Borland C++ Builder, which at it's minimum is bigger than the freeBASIC RTL anyway and isn't freely available) preferably using either the MFC, ATL, STL or pure MSVCRT.dll (did I miss any?) Which leaves MinGW GCC, or Visual C++... or derivatives like Microsoft C++ with Code::Blocks or MinGW with Code::Blocks or Bloodshed DevC++. Also note, I assume I'd probably better not go down the QT or GTK route with either base compiler for much the same reason as avoiding VCL, and I think I'd gain less from those frameworks than VCL as VCL isn't as focused on the "Visual" part of "Visual Component Library" as GTK and QT are on their widget systems. (I think?)
But that still leaves a lot of room for different implementations within those frameworks.
--- EDIT ---
Quote:
Originally Posted by lelejau
BOB, I JUST CANT BELIVE.
I had one char called ¹Ba¹
I already had 5 chars, and I was lazy to delet one, then I created anohter account.
BINGO!
Your dll appears not to support special characters!!! Its working now!
Well, after all these annoying messages, I have another feedback for you!
=D
Well... Erm. Most of the sql.dll and clan.dll don't support userID, password or character names with characters outside the range a-z A-Z and 0-9... because that's a requirement of the indexing in the SQL. I can't put a space, tab, shriek, apostrophe or anything else like that in any of those fields... and the game client won't let you type them either... so that's hardly surprising. XD
09-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
bobsobol, TBH I cant read all this book you've written =P
But, if you are trying to migrate from freeBasic to other language, I'd suggest Delphi.
You can use in-line assembly, and is very easy to create dlls with it.
My game stopped crashing right now, and I patched all the Tribe & Class already. If I find another bug I'll let you know.
But, once again, it would be nice if you implement some encryption in the *.lng file.
And, what are you testing/fixing/adding in the IntStr.dll ATM?
I posted something about patching the strings and also its alignment, as TextOut has two arguments: X and Y. I know, I worked with it in a hook in delphi, and I was able to move the text.
And what about that SS in ur first post? Some custom program to read the debug text file? :P
09-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Another language that people don't have to PAY to install, that's smaller than freeBASIC... Delphi is bigger (because of VCL) and I don't know of a "free beer" version of it. :ott1:
ini file handling, colours, alignment, fonts etc.
It's not a custom program at all. It's just my Office productivity suite. Bog standard Open Office. (Isn't that what everyone uses these days? I mean, let's face it, MS Office only advantage ever was that it was cheaper than Lotus, Claris or Corals offerings... OOo is free, both as in "free speech" and "free beer", and since Office XP MS Office has really gone down hill IMHO.)
09-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Well,I have delphi 7 Enterprise, and I didnt buy it.. hehe.
But focus in the thread, that is, in fact, very exciting :B
09-12-10
zaharavn
Re: Beta Technical Demonstration - Translation without Hexing the EXE
If another wanna edit it to hack. how to it will??? You must code function accept only string :) ^^.. I never use it. If it have finish. I will use it :D
09-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Yea... I don't want to encourage ppls to go hunting Torrents or even searching Amazon for old copies for cheap. I don't mind if it's not FOSS, but there must be a private, non-commercial use version or community edition like Visual C Express editions or SQLYog.
Closest "free" alternative to Delphi is lazarus but I honestly don't think that any Borland or GCC based tool that isn't part of the core GNU Compiler Collection (C GC, C++ CC, x86 Assembler GAS, Fortran 66 FC and Java JC) is going to be an improvement on freeBASIC... which also uses GCC for underlying operations.
MinGW (Minimal GNU for Windows) comes with headers for the Windows platform and is an near complete re-write of Microsofts Platform SDK, it links directly to MSVCRT.dll, just a VC6 does, and doesn't have the dependencies of newer VC editions, or the overhead of statically linking VC7, 8, or 9 C Runtime libraries... so that's okay. Anything else ends up linking in a custom (non C) runtime library based on MSVCRT, or in Borland compilers case, their own RTLs either static or dynamically linked.
I know, I love my BCB 6 and it is still one of my most prized software purchases. It may be very easy to create DLLs, but the dependency overhead is way worse than any GNU based tool. The RAD development with VCL is fantastic for large projects, or small tools which make no money and need to be produced quickly... but the cost is size and memory consumption, so for DLLs to import in to PT is not a great choice, I am sadden to say.
It's probably no worse than freeBASIC... but I only see it as an "alternative", it has some pluses, and an equal quantity of negatives, and also shares many of the failings of freeBASIC.
VC is well known to most people, it can produce small code, if you codebum well enough, watch what you are doing with compiler directives and keep a keen eye on the build process (don't link what you don't use, and don't rely heavily on the DLL versions of the RTL which will contain many functions your DLL doesn't use, and this is a failing in most of the sql.dll and clan.dll libraries built with MSVC7 as debug builds dynamically linked to their CRT libraries and then missing their .PDB >.<).
I also think GCC CC (C++) is still a good choice, because it links to MSVCRT.dll which is in every version of Windows since 95b, and has not changed. It's quite small, compared to it's newer VC counterparts and is pretty stable (if not completely ANSI or ISO compliant)... but it does lack an IDE, and project management through bash scripts and makefiles scare many Windows developers silly. (Code::Blocks and Bloodshed are possibilities here) I'm not good with make files my self, but I'm not great with ATL or MFC either, so if that's what people here would prefer, I will redirect my aim in that direction.
I suspect, that most people would prefer a Visual Studio Express edition solution, as that has proven to be the case in most successful projects of this nature.
09-12-10
zaharavn
Re: Beta Technical Demonstration - Translation without Hexing the EXE
DLL easy create on C++.. You can search it on Google :D
09-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I think there is another bug.
This string:
TextOutA(), 1239352, "게임을 종료 합니다", "/* Not Replaced */"
I cant patch it.. When I patch with this number, others strings will be patched too, right? I think this is the same problem we had with the Tribe & Class stuff.
Could you try to patch it bob?
09-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
"Exit Game"? How do you get the client to display that Lelejau? I can't even find that string "EA B2 8C EC 9E 84 EC 9D 84 20 EC A2 85 EB A3 8C 20 ED 95 A9 EB 8B 88 EB 8B A4 " in my client... does it maybe come from the server, and get displayed in the chat window?
If that's the case, you would need to implement International.dll in the server.
@zahara: Yes... there are very few languages you can't assign functions to export to a DLL. The point is not C++, but which C++ compiler, and what framework. VCL (Easy, but big and not free), ATL (Small, not so easy), STL (Much the same as ATL but less MS specific, and not quite so easy), MFC (Not very useful for this task I think, and bigger than ATL / STL).
There may be other OpenSource "Type Library Frameworks" and such that could be excellent for low memory usage fast access to dynamic length arrays or linked lists and string manipulation? If anyone knows a good one, I'd like to hear about it.
Maybe someone here thinks they could implement something like VCL-like TString object and String Lists in C++ (VC / GCC) and would be willing to donate such classes. Or maybe someone is really cleaver and can implement one in Assebler that they (or I) can compile to a .obj / .bin / .o and use Microsoft lib.exe to make it into a .lib file I can include at build time in Visual C++? IDK It's something I've considered.
I worked a version in ANSI C which had the right exports and stuff... but with no means of getting Mid(szString, dwStart, dwLenght) or StrObj.SubString(Start,Lenght) and InStr(String, SubString) or StrObj.InString('SubString') it's very difficult to work with strings in regular standard C.
It's very easy to do this stuff in Basic, Fortran, Pascal, PHP, Perl etc without any special typelibs or add-ons to the standard language, and not so easy to make a lightweight DLL. With Asm, C or C++, it's pretty hard, but very easy to build the DLL.
More examples of possibilities I discounted as impractical:-
The C++ strlib.h helps but doesn't quite go far enough in terms of the arrays / linked lists.
I can include SQLite and that would be awesomely easy... but as light an SQL engine as it may be, it's still way to heavy for this job.
See the problem?
09-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
this string is showed when you, in-game, press SHITF+ESC to exit the game. Or just clicking in the Exit Button.
Its like that in KPTTrans:
"Quitting SGPT!"
@edit
And, the new dll is crashing my game. After I login in Ricartem or Pilai, or whichever map, after a few seconds, the game just stops ansering. I'll reinstall my client full, but I'm not convinced that it will stop...
10-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
with the following line:-
1566976 = "Logging out..."
This is in the main threads stack space, so it's not a very "safe" place to patch it, but I don't see it appearing before it is stored there.
I haven't seen any other string placed at exactly that location on the stack, and this string seems to always appear at that location... so, while it's not safe, it does seem to be reliable.
10-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
OK, I reinstalled KPT and updated to 1988.
I added the dll, and everything seems to be fine.
Here is the 0016.lng, for 1988: (it appears to work fine in 1987, once I made it in 1987 and works - until where I checked - fine.)
Quote:
; BETA
1239352 = "Saindo do jogo..."
; First Screen
;6209776 = "Ver: 1.98.7"
6215984 = "Conectando ao EvoPT..."
6215956 = "Falha na conexão!"
6215928 = "Preencha com seus dados!"
6215900 = "Usuário ou senha incorretos!"
6214708 = "Deseja continuar?"
6215808 = "Conta já está logada!"
6215720 = "Tempo de jogar expirou."
6215836 = "Você está banido! Entre em contato com o suporte."
6137004 = "Pod. de Ataque:/n"
6136992 = "Vel. da Arma:/n"
6136968 = "Crítico: /n"
6136944 = "Taxa de Atq: /n"
6136920 = "Bloqueio: /n"
10-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Of course these are very different from the addresses in 1977.
Still, thanks.
10-12-10
zaharavn
Re: Beta Technical Demonstration - Translation without Hexing the EXE
^^. i'm happy when you and lelejau develop it :)
11-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Okay... I see the issue with the game locking up after a while. I believe it's in the MRX rain code.
It seems if you wait for a second shower to come, that's when it locks up, but I'd already noticed that it doesn't restore "ambient" sound when rain ceases, and I think there should be a "rainfall" ambient sound to accompany the thunder... so I'm guessing MRX rain is missing some code. :wink:
I'll mention it on his thread, see if together we can't crack that one.
11-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
well, I think you should disable rain in that dll. I mean, the purpose is translating texts not adding rain...
I think the speed will slow a liltle bit because of the translating. I think we should remove all the code we can, to make the dll cleaner and to make the game as faster as we can.
12-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Its not working bob. This message should be "DC Disconnected from Server.." but in Korean. But it was patched with that loging out text..
---------- Post added at 06:51 PM ---------- Previous post was at 06:34 PM ----------
Another bug.
IN the skills, we have this: (I'm assuming this is the Healing skill description.)
lstrcat(), 1243828, "신성한 마법으로 생명력을 회복 시
켜준다.", "/* Not Replaced */"
lstrcat(), 51666824, "힐링 (요구레벨:10)
신성한 마법으로 생명력을 회복 시
켜준다.", "/* Not Replaced */"
Skill Name(Level:10)
Description
And, with that same number, I found another text. So, If I pacth this, another one will patch too. I guess we have a problem..
13-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
here is what I have so far:
http://img844.imageshack.us/img844/1102/traduo.jpg
I'm currently translating the skills, which will take alot of time. Since when the skill isnt ready ( i'm not buy it yet) the strings to patch are diffrent from the skill bought.
13-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Quote:
Originally Posted by lelejau
well, I think you should disable rain in that dll. I mean, the purpose is translating texts not adding rain...
Rain = nothing to do with DLL. It's only part of the new 1977 Butchered executable I included. The crash (and rain) does not happen with the old Butchered International (without rain) regardless of which version of the DLLs you use.
The only change in the newer game.exe is the rain. Nothing else. So the DLLs work just as well with either version of the game.exe.
As to your other concerns... I'm struggling because your offsets are nothing like the ones in 1977, which is pretty much the only way I can debug them. Any report not based on one or the other 1977 based KPT really is pretty useless to me. But...
In 1977:-
Code:
7043000 = "신성한 마법으로 생명력을 회복 시켜준다."
As for your string at 51666824, that has already been string concatenated from smaller ones into a temporary buffer. (strcat() that's what it does, and where it's name comes from, you know? :wink:)
In KPT 1977 there is only one message (that I have found) "Disconnecting from server" and it appears if you hit the close box, Alt F4, the server goes off-line, or for any other reason, as far as I can tell. The Korean string is always the same, and the address it's located at is also always the same.
!!Good news!!
I've developed a tool that will extract strings, and their location from a section dump and it's hex offset.
If you open the game with CFF Explorer, go to the section headers, select .data or .rdata and right click -> "Dump section" out to a file. Then check the offset of that section in memory in OllyDbg, you can run "ExtractStrings 1977.RData 5C4000 > KoRData.txt", for example, and get a text file that is pretty much a .lng file for the original Korean.
Comparing that text file with one from an English, or Brazilian (or Chinese) executable will quickly give you a good idea of what the string is meant to mean... checking with Google Translate is a good idea too, but it gets you to the source quite quickly. :wink:
Problems I notice, having used this tool to good effect:-
Some strings in PT which are strcat() together, have \n or \r in them (0x0D or 0x0A) and this can't exist in a .ini file... so this program encodes them as "\n" or "\r" and includes "\e" "\t" "\v" and "\\" of course... it encodes double quotes as "\042"... but I'm going to have to include this in the DLLs so that they can include turn those back into the ASCII codes for "new line" "carriage return" etc. So I'm afraid I'm bumping that up ahead of offsets and colours and stuff.
If there is some memory copy routine (and I still suspect there is) which we can pin down that is causing these strings not to appear until after they have been copied out of the executable image, I will add that to the list of APIs patched... but I need to know what it is first.
13-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
WOW, I'll definately check this out.
---------- Post added at 02:48 AM ---------- Previous post was at 02:28 AM ----------
Well, it DOES "help"...
But I mean, its kind hard to find where is that string is from. I mean, with the debugger DLL, you just put the mouse in the Frenzy Armor, stays for a while and then logs out. In the txt file, you just search for Frenzy Armor and you will see everything you need to translate. With this new program, is kinda hard to do that. Can u see what I am talking?
---------- Post added at 03:13 AM ---------- Previous post was at 02:48 AM ----------
One bug, I gues.
This is the Healing skill description:
신성한 마법으로 생명력을 회복 시
켜준다
With the dll debuger:
lstrcat(), 1243828, "신성한 마법으로 생명력을 회복 시
켜준다.", "/* Not Replaced */"
This 1243828 is taken to patch, MP cost, STM cost, required level and so on, so this cant be used. Then, I used your new program and searched the txt for the decription. Found this:
7082880 = "신성한 마법으로 생명력을 회복 시켜준다."
Then, I did:
7082880 = "Cura os personagens escolhidos /n com a benção divina /n"
Nothing happens. Why?
---------- Post added at 03:20 AM ---------- Previous post was at 03:13 AM ----------
I think there's some math we have to do.
ExtractStrings:
7083116 = "홀리 볼트"
Dll debugger:
wsprintf(), 51648548, "홀리 볼트", "/* Not Replaced */"
7083116
-
51648548
=
44565432
So, we need to sum 44565432(in my case) with the number found in the dump section to patch? IDK, its my guess.
---------- Post added at 03:21 AM ---------- Previous post was at 03:20 AM ----------
well, it doenst work with the Healing skill description...
---------- Post added at 03:44 AM ---------- Previous post was at 03:21 AM ----------
and my game is crashing after a few seconds logged in. it doestn matter the map, the game always crash.
13-12-10
bobsobol
1 Attachment(s)
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I can see you've got the hang, and the point of the new program perfectly.
The address it gives is the initial address of the string when the game fist starts, and that is what we should ideally be patching. At that location it is that string and only that string. If we can't see the string being accessed at that location in the log, and therefore can't patch that location, then we are forced to patch too late.
So the question is, what routine moves the string from there to the location in which we first log it... a location which is not guaranteed to always contain that string, and only that string.
You see now why I created it? And, I think you can see it is very easy to look up the address that we should find a string at.
This wouldn't really be needed if we could search for strings in Korean in Olly, but I've not found a sensible way to do that. XD
Anyway, I suspect there is a strcpy() / memcpy() routine, possible from the MSVCRT7.1.lib which is linked into the executable which needs redirecting, but I haven't found strings which aren't being patched in my 1977 translation yet, and I can't use the addresses from your 198x version which are completely different from mine.
I know your goals are different from mine, but I'd appreciate some help from you, so that I can help you in return by making this more "all inclusive". Right now, there is clearly a *major* function which is moving text strings (or blocks of memory) without these DLLs seeing that move, and I / we need to track it down and trap it. :wink:
I hope you can now see why I need playtesting from the same exe. You've already proved that the method is easy to port to a different client exe, but unless we make it rock solid on one, we're quoting page, chapter and sentence numbers from different print editions. They don't match up, and you can't debug or trace back from that.
The section dumps help, but they're still not as good as having the address / offset from the same client version. If I go in and use Olly to trap memory access on the offsets in your client, that isn't going to show the bug in mine, it will just point me to something completely different. And if the Korean string is even slightly different in yours, I'm not going to find it's offset in mine, however I present it. :*:
I'm about ¼, maybe less through my RData section... and so far it's mostly strings that either don't come up often, or are not a problem to patch. Finding the ones you have identified as problematic is not proving easy... but I'm working on it.
Also, I'm considering allowing the .lng file to take offsets in Hex, as that should show clearly which memory section they are in, in the same manner as they are displayed in Olly. Currently, you have to take the offset and convert it to Hex to see where it is in Olly.
eg.
Quote:
Originally Posted by lelejau
wsprintf(), 51648548, "홀리 볼트", "/* Not Replaced */"
51648548 is 03141824 in Olly. I know that's probably part of the Data section which runs from 0x005F9000 to 0x0444EFF0 in my client, but the "initialised" data, only runs up to 0x00222000, which means it's been copied there from somewhere else, and we should patch that copy operation first.
You may notice that there are very few strings which need patching in the .data section... most are in .rdata... so when we can only find them after they have already left there, they are either one of the few that really are in .data, come from a file, or from the server, or are actually moved to the location at which we first find them, and that's the problem point.
What moved them? Is it a DLL API, is it a compile time linked library? Is it some specific routine they wrote directly in the C code for PT? Right now, I don't know, because you seem to find lots of them, and I can only find one... but I don't doubt that you are finding them. I just can't do much with the most of the information you are giving me, because it relates to a different base.
Speaking of which, I hope you don't have any problems with the old game.exe and the new libraries... I certainly haven't had.
Oh yea... I was also thinking to use an Exe Index file, so that we can index offsets, and only the index needs to be changed to make the .lng file work on a different executable. Does that idea appeal?
[Strings]
0000 = "Connecting to Server..."
0001 = "Connection Failed!"
0002 = "Please enter login details!"
0003 = "Invalid user name or password!"
0004 = "Continue this adventure?"
0005 = "Are you sure you want to delete?"
They could also be in the same file, with the .ini style section headers... but since the same index can be used with multiple .lng files, I thought it would save space to keep it in a separate file, unless there is a good argument against doing that. (I'm coding by democracy here XD)
rather complex routine located at 00593D60 in 1977.
Can you confirm a similar routine in your client (almost certainly at a different location) causing these memory moves?
I can see it checking the length of the string, looking for a suitable memory hole, copying it, and then making changes to the colours of the hDC for the display.
Olly thinks it takes 6 parameters, but I can see it checking a 7th, which would be something left on the stack from the former routine... and that I don't understand.
Should I reimplement this entire routine in the assembler DLL (that I probably could never re-work into C) and replace it in the exe with one that redirects to the new DLL routine, or should I force it to call strcpy() to a known clear location and then replace Arg3 with that location? That would make more sense in the long run, but is a little messy... don't you think?
It's not part of MSVCRT7 compiled into the exe... this is clearly something very custom that PT is doing. :/:
--- EDIT2 ---
That routine seems to be preparing the centre of screen dialogue texture for the text to be displayed on top of. Not entirely sure why it doesn't perform the DrawText() API on to that texture, then it wouldn't have to keep performing it on the main display after the dialogue overlay. :?:
Anyway, I've implemented the C string escape codes in IntStr.dll, now at v0.0.2 and come across another minor typo that was eating up silly amounts of memory, so (although it wont fix the texts displayed on to the centre of screen dialogues) seems to run faster, and uses less memory, despite the DLL size increase from properly breaking out C escape codes... please find it attached.
\/\/\/\/\/\/\
Note: Only implemented escape sequences are those found here. C++, and Win32 programmers may expect to find more, most notably \h0d operating the same as \n ... these uses will produce "\* error *\" instead. I don't think most are important, but when I get time I will revise the list of supported escape codes.
/\/\/\/\/\/\/\
Oh, and it's "Logging" version also logs all strings read from the .lng file, and how they are interpreted from a C escaped string (\n carriage return, \l new line etc) into a pure binary string. (This means skipping an indeterminate number of lines when importing into a spreadsheet, but I think it's useful information for developing .lng files. :wink:
13-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Bob, you didnt answer my questions, about the skill description, etc..
and one great idea is:
Quote:
Originally Posted by 0016.lng
#include descriptions.lng
55555=Test
Quote:
Originally Posted by description.lng
121211=Another Patch
You see? :P
13-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Quote:
Originally Posted by lelejau
Bob, you didnt answer my questions, about the skill description, etc...
Yes I did. At great length, though I'm not sure it's part of the same code which makes the middle of the screen displays, it will be a similar reason.
The DLLs aren't seeing those strings until they have already been moved to a generic buffer.
I don't understand your description of this "great idea". You just want "#include" so you can break the file down into lots of little ones? That could get confusing pretty fast I think. Complete translation will be under 1meg, since all strings extracted from the game, along with all offsets and other non-string data is 900 odd K in .lng form.
We're talking about a file less than 1000 lines long, even if you patch every URL, Path, INI command, ASE string and LUA instruction.
Though with those features in mind, I can see a use for a file that contains URL, SQL etc patches that will be applied regardless of language.
14-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
bob, would you mind to try to patch any skill description? I cant patch skills description here...
Would you mind?
14-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Love to. Wanna tell me how? :ott1:
The descriptive strings undergo considerable movement inside game.exe it's self.
Initially they are moved into a new table filled with all the Skill details using simple Rep MovS DWord Ptr[EDI],DWord Ptr[ESI] (this happens just after player select BTW) and later seem to go through some routine which splits them by inserting Carriage Return characters into them every X letters... I can't find that routine, and attempting to debug near it is causing fatal exceptions.
Maybe if I made the Rep MovS DWord Ptr[EDI],DWord Ptr[ESI] a strcpy() that would clear up the rest? Trouble is, I'm not convinced that the string is the only data that routine is moving... but I'll give it a shot, even if I have to move the string, and then use Rep MovS everything that isn't part of the string.
--- EDIT ---
Having humanised the initial offender as best I can, I propose moving the following routine to a space I have already cleared (along with my many XTrap and other defunct code removals) in a state altered like so:-
Code:
004ADA80 mov eax,[30FF368] ; (guessed void)
004ADA85 mov eax,[eax+0B4]
004ADA8B dec eax ; Switch (cases 1..8, 9 exits)
004ADA8C cmp eax,7
004ADA8F push ebp
004ADA90 mov ebp,ecx
004ADA92 ja short .CaseDef
004ADA94 jmp [eax*4+.CaseTab]
.Case1 mov dword ptr [ebp+14],2000000 ; Case 1 of switch
004ADAA2 jmp short .CaseDef
.Case2 mov dword ptr [ebp+14],1000000 ; Case 2 of switch
004ADAAB jmp short .CaseDef
.Case3 mov dword ptr [ebp+14],4000000 ; Case 3 of switch
004ADAB4 jmp short .CaseDef
.Case4 mov dword ptr [ebp+14],3000000 ; Case 4 of switch
004ADABD jmp short .CaseDef
.Case5 mov dword ptr [ebp+14],6000000 ; Case 5 of switch
004ADAC6 jmp short .CaseDef
.Case6 mov dword ptr [ebp+14],5000000 ; Case 6 of switch
004ADACF jmp short .CaseDef
.Case7 mov dword ptr [ebp+14],8000000 ; Case 7 of switch
004ADAD8 jmp short .CaseDef
.Case8 mov dword ptr [ebp+14],7000000 ; Case 8 of switch
.CaseDef mov eax,[ebp+14] ; Default case of switch
004ADAE4 test eax,eax
004ADAE6 je .Label4
004ADAEC push ebx
004ADAED push esi
004ADAEE push edi
004ADAEF mov eax,1
004ADAF4 mov ecx,84
004ADAF9 mov esi,006BC278
004ADAFE mov edi,03136580
004ADB03 rep movs dword ptr [edi],dword ptr [esi]
004ADB05 mov [31365E4],eax
004ADB0A mov [31365E8],eax
004ADB0F mov dword ptr [3136784],3000000
004ADB19 mov [31365EC],eax
004ADB1E mov ebx,6BC278
.Loop0 /mov ecx,[ebx+20]
004ADB26 |mov eax,[ebp+14]
004ADB29 |and ecx,FF000000
004ADB2F |cmp ecx,eax
004ADB31 |jne .Label3
004ADB37 |mov edx,1
004ADB3C |mov eax,31367F4
.Loop1 |/cmp dword ptr [eax],0
004ADB44 ||je short .Label0
004ADB46 ||add eax,210
004ADB4B ||inc edx
004ADB4C ||cmp eax,31388F4
004ADB51 |\jl short .Loop1
004ADB53 |jmp short .Label3
.Label0 |mov eax,edx
004ADB57 |imul eax,eax,210
004ADB5D |lea edi,[eax+3136580]
004ADB63 |mov ecx,84
004ADB68 |mov esi,ebx
004ADB6A |rep movs dword ptr [edi],dword ptr [esi]
004ADB6C |mov edi,[eax+31365A0]
004ADB72 |xor esi,esi
004ADB74 |mov ecx,6B0814
004ADB79 |lea esp,[esp]
.Loop2 |/cmp edi,[ecx]
004ADB82 ||je short .Label1
004ADB84 ||add ecx,12C
004ADB8A ||inc esi
004ADB8B ||cmp ecx,6BC394
004ADB91 |\jl short .Loop2
004ADB93 |jmp short .Label2
.Label1 |imul esi,esi,12C
004ADB9B |add esi,6B06F8
004ADBA1 |lea edi,[eax+3136664]
004ADBA7 |mov ecx,4B
004ADBAC |dec edx
004ADBAD |rep movs dword ptr [edi],dword ptr [esi]
004ADBAF |mov [eax+313678C],edx
.Label2 |mov dword ptr [eax+31365E4],1
push esi
push edi
call dword ptr[<&KERNEL32.lstrcpyA>]
.Label3 |add ebx,210
004ADBC5 |cmp ebx,6D0C78
004ADBCB \jl .Loop0
004ADBD1 mov ecx,88
004ADBD6 mov esi,6D0C78
004ADBDB mov edi,3138890
004ADBE0 rep movs dword ptr [edi],dword ptr [esi]
004ADBE2 mov ecx,ebp
004ADBE4 call 004AAC90
004ADBE9 mov eax,1
004ADBEE mov ecx,ebp
004ADBF0 mov [31365E8],eax
004ADBF5 mov dword ptr [3136784],3000000
004ADBFF mov [31365EC],eax
004ADC04 call 004AC740
004ADC09 pop edi
004ADC0A pop esi
004ADC0B pop ebx
.Label4 xor eax,eax
004ADC0E pop ebp
004ADC0F ret
.CaseTab dd .Case1
004ADC14 dd .Case2
004ADC18 dd .Case3
004ADC1C dd .Case4
004ADC20 dd .Case5
004ADC24 dd .Case6
004ADC28 dd .Case7
004ADC2C dd .Case8
This routine is only called from 3 locations, so those calls will need to be updated to point to the new routine. However, there is no room for manoeuvring extra instructions into this routine, and despite my best efforts I can see no way to "bum this code down". But then I still don't really understand what it is doing properly. Seems to be taking the initial table from constant memory and placing it in a variable data structure in a less compressed form, allowing room for other "properties" to be modified on-the-fly... and only moves out data appropriate to the current character class. This does give all these details a static location, regardless of the current character class, and provide room in writeable memory, but if that is truly what it is doing, why not load this from an external file, or at least use the ZLib library that's included into game.exe to extract a solid lump into the right area? Not sure... don't know that I care right now either.
This should give you an "in" to patching this string before it becomes broken down and moved into a common area for displaying all kinds of stuff.
If anyone can see a blindingly obvious reason why this shouldn't work, please speak now. :lol: I can already see that "004ADB93 |jmp short .Label2" may give me some grief. :(:
14-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
IMHO, I didnt understand nothing you said, lol.
But good luck, I know you can handle it.
15-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
7019600 = "Goes berserk for a short periodof time, but loses health with each attack"
Specifically, you have to make sure words do not stretch over the 32nd and 58th character in the string, where (if the string is long enough) new line characters will be inserted. :(:
This really does have to be fixed in the exe... there isn't a practical way to patch rep movs via DLL, but I think there is more improvement to be made by replacing code of this nature all together.
subClassSkillTable:
mov eax,[30FF368] ; (guessed void)
mov eax,[eax+0B4]
dec eax
cmp eax,7
push ebp
mov ebp,ecx
ja short CaseDef
jmp [eax*4+CaseTab]
Case1 mov dword ptr [ebp+14],02000000
jmp short CaseDef
Case2 mov dword ptr [ebp+14],01000000
jmp short CaseDef
Case3 mov dword ptr [ebp+14],04000000
ja short CaseDef
Case4 mov dword ptr [ebp+14],03000000
jmp short CaseDef
Case5 mov dword ptr [ebp+14],6000000
jmp short CaseDef
Case6 mov dword ptr [ebp+14],5000000
jmp short CaseDef
Case7 mov dword ptr [ebp+14],8000000
jmp short CaseDef
Case8 mov dword ptr [ebp+14],7000000
CaseDef mov eax,[ebp+14]
test eax,eax
je Label4
push ebx
push esi
push edi
mov eax,1
mov ecx,84
mov esi,006BC278
mov edi,03136580
rep movs dword ptr [edi],dword ptr [esi]
mov [31365E4],eax
mov [31365E8],eax
mov dword ptr [3136784],03000000
mov [31365EC],eax
mov ebx,006BC278
Loop0 mov ecx,[ebx+20]
mov eax,[ebp+14]
and ecx,FF000000
cmp ecx,eax
jne Label3
mov edx,1
mov eax,031367F4
Loop1 cmp dword ptr [eax],0
je short Label0
add eax,210
inc edx
cmp eax,031388F4
^jl short Loop1
jmp short Label3
Label0 mov eax,edx
imul eax,eax,210
lea edi,[eax+3136580]
mov ecx,84
mov esi,ebx
rep movs dword ptr [edi],dword ptr [esi]
mov edi,[eax+31365A0]
xor esi,esi
mov ecx,006B0814
lea esp,[esp]
Loop2 cmp edi,[ecx]
je short Label1
add ecx,12C
inc esi
cmp ecx,006BC394
^jl short Loop2
jmp short Label2
Label1 imul esi,esi,12C
add esi,006B06F8
lea edi,[eax+3136664]
mov ecx,4B
dec edx
mov [eax+313678C],edx
Label2 mov dword ptr [eax+31365E4],1
call subStrCpy
Label3 add ebx,210
cmp ebx,006D0C78
^jl Loop0
mov ecx,88
^jl Loop0
mov esi,006D0C78
mov edi,03138890
rep movs dword ptr [edi],dword ptr [esi]
mov ecx,ebp
call 004AAC90
mov eax,1
mov ecx,ebp
mov [31365E8],eax
mov dword ptr [3136784],03000000
mov [31365EC],eax
call 004AC740
pop edi
pop esi
pop ebx
Label4 xor eax,eax
pop ebp
ret
subStrCpy /$ push esi
|. push edi
|. rep movs dword ptr [edi],dword ptr [esi]
|. pop edi
|. pop esi
|. push esi ; /String2 => ARG.ESI
|. push edi ; |String1 => ARG.EDI
|. call [<&KERNEL32.lstrcpyA>] ; \KERNEL32.lstrcpyA
|. add esi,40
|. add edi,40
|. push esi ; /String2 => ARG.ESI+40
|. push edi ; |String1 => ARG.EDI+40
|. call [<&KERNEL32.lstrcpyA>] ; \KERNEL32.lstrcpyA
|. add esi,40
|. add edi,40
\. ret
--- EDIT --- Okay... spent some time play-testing and, no, I'm not getting any crashes during general play... shopping, hunting etc.
I do get severe locukups using the logging version both during loading and displaying player skills... but there is a lot of work put on the DLLs at those points, and that means a lot of work for the FS (which will always be slow) when logging is enabled.
16-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
There isnt enough space to make these modifications:
Are you sure that you did not something wrong there?
Maybe JMP to new section do code and jump back.
17-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I'm trying with bob's game, not mine.
---------- Post added at 10:34 PM ---------- Previous post was at 10:30 PM ----------
the crash is on
005A2FB2 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
It gives me Access violation when writing to [7E36A8AD].
The same thing happened in my attempt to "copy" what you've did. Well, I guess it wasnt my "noobiness" in ASM. Not that you dunno asm, or that u are a noob, that is not what I meant.
18-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Okay... have you "carte blanche" copied my code from my client into yours? Because I can guarantee the offsets in the instructions pointing to .rdata and .data sections *will* be different in 1988 to what they are in 1977.
I moved the code into a section that did have nonsense to do with XTrap callbacks. Those locations will also be different in 1988.
However, I am not experiencing any problems with my modified executable.[center]YT Video Vimeo Version(a little clearer)
If your media player sucks ass (you don't have the right codecs and CBA getting them and installing them) just use VLC. It's not the highest quality playback, but it is compatible with just about everything. :wink:
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I just follow what you did and did the same into mine. I know the offsets are different, and I updated then. The point is, your exe is crashing here too.
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Can you you upload bobsobol and yours .exe with all modifications and .dll, .lang files etc. that your are using?
18-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
@lelejau: Yes, I recognise that you are trying to use *my* exe when the error occurs, and appreciate how frustrating that will be for you. It is both worrying and frustrating to me too.
The instruction at which you find the error is should copy ECX bytes from ESI to EDI as they are when it is first executed, and the address it believes is out of range never occurs for me but it will now be using dynamically generated addresses created by the DLLs, and where those addresses are generated will depend on the memory layout determined by your hardware and OS. So I can't be 100% certain that the runtime library in the High level code won't allocate memory around 0x7E36A8AD on your system, but without looking at the memory map and hex dump of memory ranges around there, and probably setting an IBP @ 005A2FB2 to see what the starting values of ECX, EDI and ESI are before the REP begins... I don't know how to help this situation.
Therefore I can only evidence that I cannot reproduce the error my end.
FYI, commented disassembly of the code around your error:-
Code:
subStrCpy /$ push ESI ; Replaced rep movs DWord [EDI], DWord [ESI]
005A2FB1 |. push EDI ; Store them on the stack, as they change after Rep
005A2FB2 |. rep movs dword [EDI],dword [ESI] ; Perform the Rep
005A2FB4 |. pop EDI ; Get the stored versions
005A2FB5 |. pop ESI ; back off the stack
005A2FB6 |. push ESI ; Then pass them both on to lstrcpyA
005A2FB7 |. push EDI ; which we have replaced with our DLL version
005A2FB8 |. call [<&KERNEL32.lstrcpyA>] ; \KERNEL32.lstrcpyA
005A2FBE |. add ESI,40 ; 40h bytes in to this byte copy is the main descript
005A2FC1 |. add EDI,40 ; as the first string is just the skill name
005A2FC4 |. push ESI ; Now pass the source and destination of this
005A2FC5 |. push EDI ; on to our patched lstrcpyA
005A2FC6 |. call [<&KERNEL32.lstrcpyA>] ; \KERNEL32.lstrcpyA
005A2FCC |. add ESI,40 ; Return ESI
005A2FCF |. add EDI,40 ; and EDI to original values before
005A2FD2 \. ret ; Returning to the moved routine.
This may help you understand what is going on, around where your crash occurs.
@Vormav: This is a fantastic suggestion. It's possible that I have made more major adjustments in the minor tweaks to the DLLs I am using now, compared to the last release which I presume lelejau is still using, than I had anticipated.
The 009.lng file can only be a template for him to follow, as I know 009 is not his primary language code. However I have posted all dependencies together with this executable (which should be identical to the one he already has) >here<.
Including:- SetLogging.cmd (which I still don't know why lelejau has trouble running) PTInternational.exe Should be the same as the last quick release post. International.dll (I'm fairly certain hasn't changed) IntStr[Release].dll v0.0.2 Build 17 IntStr[Logging].dll v0.0.2 Build 17 HanDes.dll (Just in case XD)
--- EDIT ---
I should mention that while this decodes C style "/r/n" codes in the .lng file, it isn't re-encoding them, when logging. I have already noticed that this needs to be done, as it makes a mess of the import into a spreadsheet. XD
---/EDIT ---
As far as I was aware I have only been tweaking the build process to help me synchronise the build numbers of Logging and Release libraries, (a lot of #ifndef stuff, to allow me to pass logging or not to the fbc on the command line) but please do try out both these libraries and let me know how they are operating on your systems.
@both / all
Thank you so much for your continued patience, help and advise. It is much appreciated.
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
There is a little error in your PTInternational.exe that leading to crash when you quitting game.
To fix it replace:
Code:
005B5DF2 E8 3F3F0000 CALL PTIntern.005B9D36
With:
Code:
005B5DF2 . E8 313F0000 CALL PTIntern.005B9D28
...unless you planed that >=P
PS. I don't like that windows cursor in your PT XD
18-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Quote:
Originally Posted by Vormav
There is a little error in your PTInternational.exe that leading to crash when you quitting game.
To fix it replace:
Code:
005B5DF2 E8 3F3F0000 CALL PTIntern.005B9D36
With:
Code:
005B5DF2 . E8 313F0000 CALL PTIntern.005B9D28
...unless you planed that >=P
I didn't intend it, and haven't altered that code from the original 1977. Just checked, and you are quite correct. I have no idea how that has gotten like that. :S Thanks for pointing it out.
Quote:
Originally Posted by Vormav
PS. I don't like that windows cursor in your PT XD
lol, so turn it off, I explained how in the Butchered thread, there is even a tool to switch one or the other cursor there, it should still work. I personally turn off the software cursor, but I do still need to make the hardware cursor represent the normal PT shapes. (not hard, just haven't gotten around to it)
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
ok. Now, I tryed with your game. When I try to use the dl to patch the strings the game closes before I have a chance to type username and password.
(With International.dll and IntStr.dll, I'm saying.)
Access Violation when writting to
DS:[ESI]=[006D0CBC]=00000222
DS:[EDI]=[04C41024]=2001058F
I'm having too much errors here. My game crash with no reason sometimes, this skill thing doesnt work (with ur game and with mine)... I am really sad. This was an awesome project, and I really would like to complet it. But, its becoming annoying, with all these errors and stuff.
Help me bob :(
There isnt another way to patch the skills description?
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Can you upload your .lng file?
What OS you are using?
I do not experience any problems so I believe it might be your OS/settings or error in .lng file.
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Windows XP.
Here is my lng:
Quote:
;Frases da tela inicial.
;6209776 = "Ver: 1.98.7"
6215984 = "Conectando ao EvoPT..."
6215956 = "Falha na conexão!"
6215928 = "Preencha com seus dados!"
6215900 = "Usuário ou senha incorretos!"
6214708 = "Deseja continuar?"
6215808 = "Conta já está logada!"
6215720 = "Tempo de jogar expirou."
6215836 = "Você está banido! Entre em contato com o suporte através do site."
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Problem is not in your OS or game.exe, its in your .lng file.
You have wrong addresses, for example:
in bobsobol:
6197848 = "Connecting to Server..."
in yours:
6215984 = "Conectando ao EvoPT..."
You can't use .lng from yours (1.98.8?) game.exe in PTInternational.exe
So you need a different .lng file for different version and if yours crash with yours game.exe than you have some mistake in .lng file.
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
My game is a different version than bobsobol's.
Mine is 1988 and his is 1977. Everything works fine here, but the skills desc not.
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Take bobsobol 009.lng and translate it (without touching addresses in front of translation), start PTInternational.exe, magic happen no crash :)
You probably made some mistake in your game.exe version/address in .lng file but I can't tell, I never sow yours (the one you uploaded was "clean", I think).
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I already said, bobsobol's game is crashing here too!
Without any lng file.
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I just tried on Win XP, with same result everything is working for me.
Try putting bobsobol files into clean KPT client folder.
If you have different OS than can try it too?
If that will not help than can you start giving offsets from PTInternational.exe, because its too confusing and I am not sure about what .exe you are talking about.
I recreated your error and error you are having occurring because memory is patched in wrong place, in other words your .lng file have bad address and data that was patched is moved to EAX.
I know you are not a noob but people making mistakes or "magic happen" like error I found in PTInternational.exe.
So I will ask again if you can you check this:
Install fresh KPT,
put files that bobsobol uploaded inside that folder,
do not change 009.lng,
run PTInternational.exe
PS. remember to rename IntStr[Release].dll to IntStr.dll
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
well, I'll do it. Thanks vormav.
---------- Post added at 06:58 PM ---------- Previous post was at 06:44 PM ----------
I didnt find any PTInternational.exe, only ButcheredIntlClassDescFixvA.exe.
18-12-10
bobsobol
Re: Beta Technical Demonstration - Translation without Hexing the EXE
First of all, thank you for the positive report Vormav. I'm glad the current system seems to work as well for you as it does for me.
The confusion here is that Lelejau and I are trying a two pronged attack at the issue he is having. Neither are proving succesful at the moment. But we are trying either to get his 1988 client to work, or my Butchered 1977 client to work... right now both are crashing on his PC, OS, and configuration.
Quote:
Originally Posted by lelejau
ok. Now, I tryed with your game. When I try to use the dl to patch the strings the game closes before I have a chance to type username and password.
Yes, username and password both pass through the APIs which are patched, so if the dlls are conflicting with your system then even they may be compromised. And I think that's what it's down to... a conflict between my present DLLs and your PC setup, as we should now have covered everything related to the game, with the possible exception of the assets. (meshes, animations, sounds and textures)
(In your exe.)
Access Violation when reading.
DS:[0000029C]=???
EAX=0
Well, it's quite correct, 29C is still part of BIOS memory which is protected by the 386+ "Protected Mode" Windows runs the CPU in... it's the space the BIOS takes up that stops you using up-to the 4Gig limit of the 32-bit address space in the machine, unless you enable PAE (Paged Addressing Extensions) to page the BIOS out... and support them in your application. (OT, sorry) But that is why that address will always be invalid. So if EBX+29C = 29C then when the instruction at 0x004567E3 is called EBX = 0, and it should not; EVER!
This is not a routine I have ever modified, nor is it ever directly called from any routine I have ever modified... so something my DLLs are passing back must be incorrect on your system, leading to problems further down the line. I would like to know what the last line the "Logging" version outputs is before that error occurs.
Quote:
Originally Posted by lelejau
There isnt another way to patch the skills description?
I'm sure there are other ways of implementing the changes to the executable than the method I chose... you could move the code to a new section, I could implement it in International.DLL which would fix International.DLL firmly to MY client only. You could "break out" each of the REP MOVS instructions to a completely custom routine which scanned for strings. I don't think any of those things is going to improve your situation.
However, simply re-writing IntStr.dll in C++, might... equally, if it was C++ switching between VC6 and VC9 may create or remove this problem... that's not really a solution, because it doesn't explain what the problem is.
What the problem is, is clearly something to do with how memory is allocated on your PC (which could be msvcrt, kernel32, advapi etc. and their interaction with GCC or specifically the freeBASIC runtime, or neither) and how the original APIs return information. (which is entirely down to Kernel32 and User32 and ADVAPI)
In any event, I don't know what OS Vormav is running, but I would guess it isn't XP, and am thinking I have an incompatibility with XP.
--- EDIT ---
Just read the last two posts... so it's not XP! :o I'm very confused now. XD
And, yea, I've been working on Butchered for months now... I never just "search and replace", never Hex, never Binary copy and paste code, (only data) and don't remember doing anything around there, unless it originally pointed to some XTrap code and I made a typo. That's about the only way I could think that it might have gotten there.
I've used addresses that I know won't get patched before too, and not had a problem. (it just wastes time)
It would be great to see the .lng line you used to re-create the issue Vormav... that way, I may be able to filter out, and warn about such "invalid" configurations. I had already considered creating memory "zones", so I could bypass logging anything too dynamic to be worth bothering with. But a lot of that's pretty specific to 1 game.exe on 1 OS, and I'm not sure that many devs / translators would know how to "zone" their own memory maps. XD
---/EDIT ---
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
OK, reinstalled everything and bobs game is normal.
**Without any Skill patch!**
I`ll try to patch the skill desc right now.
---------- Post added at 07:09 PM ---------- Previous post was at 07:06 PM ----------
Nope, it didn't work.
I'm still having crash, in a fresh KPT full client install.
His game crashs even if I patch the skill desc or not...
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
Win 7 and XP here, and for some reason I don't have bug that lelejau is talking about.
To recreate his error just put:
Code:
6136992 = "Vel. da Arma:/n"
inside 009.lng (use your game.exe 1977)
game will crash in 004567E3 as lelejau saying.
18-12-10
SheenBR
Re: Beta Technical Demonstration - Translation without Hexing the EXE
vormav, I using bobsobols files inside a fresh kpt install.
I`m still getting erros.
18-12-10
Vormav
Re: Beta Technical Demonstration - Translation without Hexing the EXE
I know, I am just telling bobsobol how to recreate your error because Its hard to fix something if you don't get that error too. Can you try different OS? Or ask some friend if he can run this for you, he don't need server.