about aoc savechapter tool

32 views
Skip to first unread message

biegleux

unread,
Jan 20, 2010, 10:03:59 AM1/20/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I must say I had no idea what are these chapters for before all these
chapter tools.
As we know we can pick non-standard (other than slow, normal, fast) game
speeds for single-player game, as well as game can be paused for a
while, another issue is lag while playing. So maybe it would be
desirable to synchronize our timer with the game's clock. There are
several timers in the game, one can be found at address
[[[[[[age2_x1.exe + 0x0026B028] + 0x1C] + 0x58] + 0x04] + 0x60] + 0x0164]
indicating elapsed time in ms (truncated). You can read it using
ReadProcessMemory(). Not sure how many different compiled exe's are
around, I have tested it with 1.0e patched file (md5checksum:
cb15bcfafffbc3ba80f307d41f50e546) so it may not be compatible with other
ones.
Maybe it can be added as an additional feature along present timers in
next releases if any planned.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAktXG18ACgkQxCk37Qku6WPFxwCggv+zLnicW04wzLr7v+m9pvY+
P6oAnAyg7xrNv7QuRv7EfeBZkxpX0y9a
=xch3
-----END PGP SIGNATURE-----

BugA

unread,
Jan 20, 2010, 11:32:43 AM1/20/10
to aoc-dev
Thank you for this info :)

Well, I didn`t meant at first my program to be as accurate as
possible, it should have only be a little help for chapter saving, but
after this e-mail from you, it sounds as a very good and usable
idea :) Also, this would make it possible to avoid a problem that I
have with the very start of the game - currently timer starts when
user activates it, so it doesn`t start when the game (match) itself
starts, making the timer inaccurate. With this info from you, this can
be corrected :)

I was thinking to make possible for user to choose different points in
time for chapter saving, for example to save chapter on 05' 00", then
10' 00", then 20' 00", and after that on every 20' 00" minutes (for
example). With the info you gave, this idea will have much more sense
than with current not-so-accurate timer :)

Thanks again, I look forward to implement this, giving you the
deserved credits ;)

biegleux

unread,
Jan 21, 2010, 3:12:35 PM1/21/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'm sorry, but it isn't as accurate as possible, because the value is
already truncated so we will hardly miss some miliseconds :( (joking :)
No need for credits, it's just an idea and probably won't work for every
age2_x1.exe (timer can be found at another address for another compiled
exe). Also I have not tested it against zone clients if they do some
memory protection or not. I would like to use this tool while replaying
a game as well (F12 key, but without further user interaction, but it
needs more research on this topic).
You can find attached simple code snippet how I usually read process memory.

Anyway it is still like an experimental idea, will try to research it
more closely so we can be sure about addressing.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAktYtTMACgkQxCk37Qku6WP2aQCeJwWGBUYItfM4cpHxXPklRWOL
mmoAninDtV4dtRaJuOlJtVDzJ4gY1OF8
=WU1o
-----END PGP SIGNATURE-----

elapsedtime.dpr

BugA

unread,
Jan 21, 2010, 3:38:06 PM1/21/10
to aoc-dev
Thanks, I already managed it to work (writing it in Visual Studio 2008
C#) :)

Yeah, damn truncation :p

But I have some kind of a problem at the moment. It worked a few
times, I tried closing and starting AoC again, pausing and unpausing a
game, changing game speed, and it all worked well -- but now it
doesn`t work :( It returns "ffffffff" as the value...? I haven`t
changed anything, I don`t get it at the moment, but I hope I`ll solve
it soon (starting to get frustrated :p)

I don`t know of memory protection, if there is any - it is surely not
a good thing for our timer. Well, I guess I`ll be banned from the
Voobly server while testing if there is any protection :))

I didn`t get the F12 thing... Isn`t it used to save a game? Why would
you need that one while replaying a game?

Thank you very much for the work you do, and for helping me :)

>  elapsedtime.dpr
> 2KViewDownload

Igor Djordjevic

unread,
Jan 21, 2010, 5:37:38 PM1/21/10
to aoc...@googlegroups.com
I give up (for now) :((
 
I don`t get it why it doesn`t work. It was working (and I must admit I was very hapy because of it), but now it desn`t. As much as I can remember I haven`t changed anything (but maybe I`m wrong :( ), and now it always shows "-1" as a label value (instead of timer time in ms).
 
Here`re the sources, any help appreciated :(
 
I will continue trying to make it work, but maybe someone comes up with a solution before I do.


--- On Thu, 1/21/10, BugA <buga_...@yahoo.com> wrote:
mem reader.rar

BugA

unread,
Jan 21, 2010, 6:29:11 PM1/21/10
to aoc-dev
Never mind my last e-mail, I found another timer :))

It`s always on address 0x00DAA134 of our "age2_x1" process. I couldn`t
believe when I saw that its does not change, but I checked it and it
is always the same. Please check this one and confirm if it is true :)

By the way, do you have MSN, or ICQ?

My MSN is buga_...@yahoo.com , ICQ# 66516695 (but I almost don`t
use ICQ anymore).


On Jan 21, 11:37 pm, Igor Djordjevic <buga_jun...@yahoo.com> wrote:
> I give up (for now) :((
>  
> I don`t get it why it doesn`t work. It was working (and I must admit I was very hapy because of it), but now it desn`t. As much as I can remember I haven`t changed anything (but maybe I`m wrong :( ), and now it always shows "-1" as a label value (instead of timer time in ms).
>  
> Here`re the sources, any help appreciated :(
>  
> I will continue trying to make it work, but maybe someone comes up with a solution before I do.
>

> --- On Thu, 1/21/10, BugA <buga_jun...@yahoo.com> wrote:

>  mem reader.rar
> 63KViewDownload

BugA

unread,
Jan 21, 2010, 6:44:10 PM1/21/10
to aoc-dev
Not true... This address changes, too :(

I`m going to sleep now.

> On Jan 22, 12:29 am, BugA <buga_jun...@yahoo.com> wrote:
> Never mind my last e-mail, I found another timer :))
>
> It`s always on address 0x00DAA134 of our "age2_x1" process. I couldn`t
> believe when I saw that its does not change, but I checked it and it
> is always the same. Please check this one and confirm if it is true :)
>
> By the way, do you have MSN, or ICQ?
>

> My MSN is buga_jun...@yahoo.com , ICQ# 66516695 (but I almost don`t
> use ICQ anymore).
>

BugA

unread,
Jan 21, 2010, 7:23:20 PM1/21/10
to aoc-dev
And now it doesn`t change whatever I do - exit AoC completely and
start it again, start new game without closing AoC completely, change
game speed... I always read timer successfully at that address
0x00DAA134 . Hm....?

That address is found as [edi + 104], while EDI = 00DAA030. Pointer
that points to this address is at 0x00DAA220. So it is [[0x00DAA220] +
0x0104] = value of game timer. Though, I know once I got different
values, and different offset, but I can`t recreate that now, I always
get this values.

I won`t spam anymore (for now ;), please check all my previous posts
and reply when you can, thank you :)

p.s. Now I definitely go to sleep :)

Message has been deleted

BugA

unread,
Jan 22, 2010, 5:24:30 AM1/22/10
to aoc-dev
I compiled and tried your "elapsedtime.dpr" file, I get that "-1 ms"
value, too :(

I managed to get another "false static" address of timer value, it was
0x00dabfe4 this time ( [[0x00daa6e0] + 104] ). Now it is again
0x00daa134 ( [[0x00daa220] + 104] ), like the most of the time on my
computer -- but the problem is it sometimes changes. I can`t find out
where`s the pointer for that first value ( 0x00daa220 in most of the
cases, or sometimes 0x00daa6e0 or something else).

I`m using the "age2_x1.exe" file you mentioned (md5checksum:
cb15bcfafffbc3ba80f307d41f50e546).


>On Jan 21, 9:12 pm, biegleux <biegl...@gmail.com> wrote:
>

> I'm sorry, but it isn't as accurate as possible, because the value is
> already truncated so we will hardly miss some miliseconds :(  (joking :)
> No need for credits, it's just an idea and probably won't work for every
> age2_x1.exe (timer can be found at another address for another compiled
> exe). Also I have not tested it against zone clients if they do some
> memory protection or not. I would like to use this tool while replaying
> a game as well (F12 key, but without further user interaction, but it
> needs more research on this topic).
> You can find attached simple code snippet how I usually read process memory.
>
> Anyway it is still like an experimental idea, will try to research it
> more closely so we can be sure about addressing.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
>
> iEYEARECAAYFAktYtTMACgkQxCk37Qku6WP2aQCeJwWGBUYItfM4cpHxXPklRWOL
> mmoAninDtV4dtRaJuOlJtVDzJ4gY1OF8
> =WU1o
> -----END PGP SIGNATURE-----
>

>  elapsedtime.dpr
> 2KViewDownload

biegleux

unread,
Jan 22, 2010, 5:36:59 AM1/22/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sorry for the confusion, looks like there are lot of false positive
pointers although your program still works for me. Unfortunately,
address 0x00DAA134 is always uninitialized to me. I did some pointer
hunt and found few other candidates looking similar (attached txt file)
if you can check them.

Fragmet of code changing this timer is as follow
...
004d5dfc add edx,000003e8 ;time in edx += 1000ms
004d5e02 mov [edi+00000104],edx ;our address is in edi (+offset)
...
It would be possible to directly read the value of edx or edi, but it
requires write access and I guess that woudn't be much friendly with
voobly client. If none of the pointers really work, I will try to find
another timer.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAktZf8oACgkQxCk37Qku6WP9IwCfaF/4SU8tC9s0muUBO3ZSLEbd
v20An03EP0q2hKQE2RVoIk3ELDxXy0+K
=B55Q
-----END PGP SIGNATURE-----

ptr.txt.txt

BugA

unread,
Jan 22, 2010, 6:19:19 AM1/22/10
to aoc...@googlegroups.com
No problem, the only time when there is no confusion is when there`s nothing at all, no work = no confusion :p :)

I tested addresses you sent, and half of them work, half not. Those that worked found game timer on that 0x00daa134 address again :p Addresses with + 0x70] + 0x0104] at the end worked. I`m sending you file with results for each address.

I will now try to test the working addresses when this 0x00daa134 changes, to see if some of them will point to the changed (correct) address, or will stick with 0x00daa134 (making these pointers false, too).

ptr - checked.txt

BugA

unread,
Jan 22, 2010, 6:46:11 AM1/22/10
to aoc...@googlegroups.com
I did test 2 -- game time value was now stored on address 0x00dabfe4 (not on that 0x00daa134 like in the first test), and I used the pointers that passed the first test (pointing to 0x00daa134). This time, all the pointers passed the second test :) All the pointers pointed to the new (correct) address -- 0x00dabfe4 .

I`m sending test 2 results.

I`ll try to do more tests, with different correct addresses of the game timer value, but for now those pointers look good ;)


>--- On Fri, 1/22/10, BugA <buga_...@yahoo.com> wrote:
>
> From: BugA <buga_...@yahoo.com>

> Subject: Re: about aoc savechapter tool

ptr - test[2].txt

BugA

unread,
Jan 22, 2010, 8:19:47 AM1/22/10
to aoc...@googlegroups.com
I did some more tests, and it looks like the value is always found correctly :)

I`ll stick with this one:
[[[age2_x1.exe+0x002B4ACC] + 0x70] + 0x0104]

I haven`t tried the rest, but that one works good for now.

When you find the time try that one for youself, to see if it works for you too.

And the good news is that it works with both 1.0c (no-cd) and 1.0e (no-cd) versions of the game ;)

"age2_x1" md5 hash = F27238DFA1C3EC444152C85F01AF30A0 (ver 1.0c)
"age2_x1" md5 hash = CB15BCFAFFFBC3BA80F307D41F50E546 (ver 1.0e)

I tried it with v1.0 and it doesn`t work, but that was expected.

I`m thinking to make a md5 checksum comparison when user selects the option to synchronize program with game`s clock, to warn him if he has a wrong version of exe file, so the program might not work well.

It only needs to be tested online, if the program works (and I don`t get a ban because of the anti-cheat :p), then it`s great :)

BugA

unread,
Jan 22, 2010, 9:53:34 AM1/22/10
to aoc...@googlegroups.com
I did some online (Voobly) tests. We had 5 possible pointers after the second test, so I checked them online.

Only two passed the third test.

I managed to successfully read the game time value (and not get a ban :p) in a few games in a row with these two:
[[[age2_x1.exe + 0x002B7668] + 0x70] + 0x0104]
[[[[[[age2_x1.exe + 0x0026B018] + 0xE8] + 0x00] + 0x0424] + 0x70] + 0x0104]

I attached results of the 3rd test (online, Voobly).

I hope these two will stand for good, or at least one of them :)

ptr - test[3].txt

biegleux

unread,
Jan 22, 2010, 10:03:05 AM1/22/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

As for now, all pointers work for me. When the game ends all of them are
zeroed except this one [[[[age2_x1.exe+0x002B3518]+0x00]+0x70]+0x0104]
which points to unallocated space in memory.
I guess if it would work it should work for all exe files with the same
entry point RVA = 0x00217522. Maybe it can be compared against this
value rather than it's md5 checksum. Should work with VEG's windowed exe
file as well, but doesn't work with boekabart's exe, but maybe we could
try to find offset also for it, but I don't know how many different aoc
files are around.

You can use similar function to read exe's address of entry point:

function getAddressOfEntryPoint: DWORD;
var
fs: TFileStream;
idh: IMAGE_DOS_HEADER;
ifh: IMAGE_FILE_HEADER;
AddressOfEntryPoint: DWORD;
begin
Result := 0;
try
fs := TFileStream.Create('age2_x1.exe', fmOpenRead);
try
fs.Read(idh, SizeOf(IMAGE_DOS_HEADER));
fs.Seek(idh._lfanew, soFromBeginning);
fs.Seek(SizeOf(DWORD), soFromCurrent); // skip signature

fs.Read(ifh, SizeOf(IMAGE_FILE_HEADER));
if (ifh.SizeOfOptionalHeader > 0) then
begin
fs.Seek(16, soFromCurrent);
fs.Read(AddressOfEntryPoint, SizeOf(DWORD));
Result := AddressOfEntryPoint;
end;
finally
fs.Free;
end;
except
//
end;
end;


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAktZvikACgkQxCk37Qku6WMg3QCfcVOF632R0njHUmn0bwJBsOyX
XMAAn0fdCtJCApNTxgxf/6q41TkgCe+b
=098K
-----END PGP SIGNATURE-----

biegleux

unread,
Jan 22, 2010, 10:22:35 AM1/22/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Didn't noticed your last post, nice to hear that. Heh it's like a
dodge-ball. I have just tested those two ptrs at gameranger and they are
still in the game.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAktZwrsACgkQxCk37Qku6WO/8ACfWnpICyRGUZZdenhE+3Lq5rJf
KUcAnREjFiiYZUMFiqqukDV8fw38hFR0
=QwXi
-----END PGP SIGNATURE-----

BugA

unread,
Jan 22, 2010, 11:23:04 AM1/22/10
to aoc...@googlegroups.com
> --- On Fri, 1/22/10, biegleux <bieg...@gmail.com> wrote:
>      

Well, it is true :) It works with VEG`s file, too. It shouldn`t be a problem to check that entry point, I think one of the classes has it as a property, but thanks for the code anyway :)


> --- On Fri, 1/22/10, biegleux <bieg...@gmail.com> wrote:
>
> Didn't noticed your last post, nice to hear that. Heh it's
> like a
> dodge-ball. I have just tested those two ptrs at gameranger
> and they are
> still in the game.
>

I didn`t get this - how do you mean they`re still in the game? Are these two pointers working at GameRanger, or not?

[[[age2_x1.exe + 0x002B7668] + 0x70] + 0x0104]
[[[[[[age2_x1.exe + 0x0026B018] + 0xE8] + 0x00] + 0x0424] + 0x70] + 0x0104]

If they work, it`s really great :))


BugA

unread,
Jan 24, 2010, 12:09:56 AM1/24/10
to aoc-dev
It`s finished :))

I uploaded the program to our files section, and it can be found here
(for now) -- http://www.aocgroup.com.ar/viewtopic.php?p=171909#171909
.

I finished everything, and when I was doing some final tests, I
realizes that it sometimes DOESN'T WORK... I was very frustrated, I
spent almost an hour testing and trying to figure it out why it just
stops working occasionally - when I saw the problem :p Our address,
keeping game_timer value, sometimes, while saving a chapter, becomes
ZERO. It happens only for a small period of time (a few ms?), but it
was enough to reset my timer and ruin the saving process. And I needed
to reset it when that value is zero, because of restarting timers on
game restart (and on complete relaunch of the game).

The solution was to make some kind of "ZeroProtection", I made it by
freezing the app for 500 ms when game_timer = 0, then rechecking it
again. If it was 0 again, then my timers should be reseted. If it
wasn`t 0 after the Sleep(500) (original value returned), then it means
we successfully outsmarted the "chaotic zero jumps" ;) "Zero
protection" disables upon real zero, and starts again when game_timer
> 5.

Phew, six in the morning, I`m definitely going to bed now... zzz... :)

BugA

unread,
Jan 24, 2010, 8:48:24 AM1/24/10
to aoc-dev
lol, after some sleep I just realized that instead of "zero
protection" I could simply test if ( save_chapter_time < game_time ),
and if so, make save_chapter_time take next value until it is >
game_time :p

That was the main problem I had, because of the unexpected zero value
of game_time, my next chapter save checkpoint (time value > game_time)
becomes < game_time, so next chapter save can`t occur ( game_time =
save_chapter_time ) and timer is stuck.

I will probably change it for next version as it is a better solution,
but I need some more thinking about it. I`ll upload sources later,
when I come back home from work. I did some code optimization this
time, but maybe it could be optimized even more (because it almost
always can be optimized more :p).

If you find any bugs or you have any suggestions, please reply,
thanks :)

BugA

unread,
Jan 25, 2010, 3:34:44 AM1/25/10
to aoc...@googlegroups.com
Here are the sources for v1.0, feel free to laugh at my "zero protection" late-night-last-moment-instant solution :))

(I`m sending this message third time, last two times like it wasn`t sent...?)


--- On Sun, 1/24/10, BugA <buga_...@yahoo.com> wrote:

> From: BugA <buga_...@yahoo.com>
> Subject: Re: about aoc savechapter tool

AoC_SaveChapterTool_v1.0_sources.rar

BugA

unread,
Feb 1, 2010, 5:09:02 AM2/1/10
to aoc...@googlegroups.com
New version uploaded (1.1), here are the sources :)

version 1.1 (01/02/2010)
------------------------
- Suspend Explorer (.exe) option added (trying to fix problems on Windows Vista/7)
- Game filename is not important anymore (it had to be either "aoc.exe" or "age2_x1.exe" in the previous version)
- Chapter saving logic improved (prevented potential bugs)
- Small GUI (graphic user interface) changes


AoC_SaveChapterTool_v1.1_source.rar

biegleux

unread,
Feb 23, 2010, 2:41:26 PM2/23/10
to aoc...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nice work,
good you solved newly arising issues.
I hope I can try it on win7 in a short time.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)

iEYEARECAAYFAkuEL2UACgkQxCk37Qku6WP4SgCcDaUifl9Qa0MfQweXffzMlghZ
h0IAn0XJ+vw92dhyLrNkTzldLpLWkHVF
=WOA6
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages