• Welcome to Valhalla Legends Archive.

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Ringo

So yeah lets see how long this takes to get fixed. :)

When blizzard wrote their IP ban module, in the event of an IP being added that is already banned, they never botherd to compare times and use the highest one, they just overwrite it.
So if you get a long IP ban, then after, a short IP ban, it effectivly over writes the long IP ban with the short one.

Orginaly, you would connect 8 bots to bnet, 7 would do cdkey test/invalid cdkey, and the 8th would chat spam (or somthing), changeing the 2week IP ban to 10mins or so. Hence the introduction of kick all clients on the given IP in the event of an IP ban.
They appear to have used the same ip ban module in all of their servers (maybe the newer ones to, I cant verify cos I dont use them)

Anyway, the kick all clients, is only subject to the battle net game protocol. HINT HINT HINT
Apon IP ban, all game protocol clients will get kicked, however, FTP clients (and the sevrer protocol) will not. HINT HINT HINT
FTP protocol has no limit on number of clients that can be connected to it on the same IP Address. HINT HINT HINT
IP ban on the FTP for the same kinf of offence on the game protocol,  are not always the same. HINT HINT HINT

:-X :-X :-X :-X :-X :-X :-X :-X ::)
Fun Forum™ / Friendship Algorithm
June 30, 2011, 02:48 PM
The Big Bang Theory - The Friendship Algorithm
Friends are plenty with the friendship algorithm  :D
Nyan Cat [original]

Nyan cat is in your head now. NYAN NYAN.
<3 =3 for directing me to Nyan cat.
I've been meaning to update the D2GS Packet Research post since for ever, as I dont think I changed much from the orginal list, posted around 2 weeks into the orginal 1st glance research.
I found a few random txt's and source codes on my comp and started refreshing/adding to the list -- I think theres almost 100 S>C packets documented now, altho descriptions are slim, to fit it all in one post.
It's been a year or 2 since I even thought about D2GS, so theres bound to be some typo's/error's/etc's in the list, so feel free to point them out and laugh, :p.
Theres still a fair few packets not listed, but as a starting/basepoint list, it should be alot better than it was(?).

I was also thinking, if I get the time/sudden will again, of adding a post with links to posts explaining how to carry out a number of common yet slightly complicated actions with in D2GS, such as, but not limited to "packet definition of how to; use a waypoint, use a teleport, trade/shop with town NPC,  how to etc the etc when you're etc, etc.", etc.
Feel free to add ideas on that!

I've also added somthing about C>S 0xFF packet, in the D2GS Packet Research C>S thread, if anyones interested.
I've known about this packet for some years after obtaining its packet ID, lengh and format, via brute forceing. I've only told 1-2 ppl about it and its format, so I would assume it's still very much secret/unknown.
I would be iterested to see/hear what peoples theorys are/what they find out about the values in the responce to this and/or the request its self :p
Basicly, connect to any closed D2GS, it doesn't matter if you have an invite from the d2gs/realm or not as you don't need to login/enter.
After connecting you will recv the tippical 0xAF packet, with the payload of the 0x01 byte to say data compressed, etc.
Now send;

FF 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00

You will then recv an always uncomressed responce, like;

01 00 00 00 00 01 00 00 00 06 00 08 00 38 00 CA       .............8..
00 FF FF FF 7F FF FF FF 7F 00 C0 80 C5 00 20 47       .............. G
D6 87 13 00 00 BC 21 00 00 44 32 47 53 20 63 6F       ......!..D2GS co
6D 70 69 6C 65 64 20 61 74 20 31 34 3A 33 37 3A       mpiled at 14:37:
30 36 20 6F 6E 20 46 65 62 20 32 30 20 32 30 30       06 on Feb 20 200
37 20 52 45 4C 45 41 53 45 00 00 00 00 00 00 00       7 RELEASE.......
9C FC D5 06 0C 1A 99 6F 00 00 00 47 A8 B5 57 7C       .......o...G..W|
00 00 00 00 00 00 00 00 01 00 00 00 DB B3 57 7C       ..............W|
0C 21 00 00 00 00 00 00 00 00 00 00 79 23 96 6F       .!..........y#.o
0F 97 57 7C 64 24 96 6F E4 88 59 7C 00 00 00 00       ..W|d$.o..Y|....
00 00 00 00 10 27 00 00 E4 19 00 00 00 17 00 00       .....'..........
00 F4 01 00 00 1F 00 00 00 00 04 00 00 04 00 00       ................
00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00       ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ................
00 9A 02 00 00 01 00 12 00 01 00 02 00 01 00 00       ................
00 00 00 00 00 00 00 07 00 05 00 01 00 01 00 04       ................
00 00 00 00 00 01 00 01 00 03 00 03 00 00 00 14       ................
00 00 00 09 00 00 00 16 00 00 00 00 00 00 00 00       ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ................
00 00 00 00 00                                        .....

Apart from the D2GS's uptime system structure, at offset 0x02, and the compile info string, you're guess is as good as mine on the other values-- some of them change every request, some of them remain constant, they could just be some random memory block, or mean somthing to the admins who would normaly use this packet(?).
I just spammed it back and forth once, sold some sojs in agame on the same server, and didn't notice anything move in releation, so never looked into any of those many many other dwords. Theres b ound to be a few easy ones, like number of open games on server, number of clients on server, etc. :)
Keep in mind i've not probed this in 1 to 2 years, but I litterly just tested it, and it still works, altho, the current D2GS is new'er, "D2GS cmpiled at 09:12:18 on May 28 2008 RELEASE".
Just a heads up, now warden is active once more;
I'm sure some of you have noticed, but for those of you that haven't:
Since wardens been enabled again, the responce to a "Page check" had changed, somtime between *then* and now -- it's no longer just null byte, it's 0xE9.
This is the 1st time i've noticed blizzard do somthing sneaky like this.
Basicly, this mean's (it always ment this, but you should be extra aware of it), when the warden module changes, you wont know for sure the responce you send back for a pagecheck, is valid. (it's been 0xE9 for the last 2 warden modules) You could be reporting you're self as cheating and never know it untill you're account was closed.
So unless you're reading this value from the downloaded warden module (to detect a value change, etc), next time this number changes, you may become a fallen warden victim.  :P

note: if you're useing a public warden handler/code thats floating around, you may want to double check, that it sends the result it reads from the ini file, for pagechecks. Because SCGP/modWarden.bas all have 0x00 hardcoded.

Heres a list of offsets/responce values etc (treat page check B as page check A's, and you should be *ok*)

game.dll&H356F3E_5=66 85 C0 76 04
game.dll&H283504_7=8B C8 BA 01 00 00 00
game.dll&H361E93_7=E8 A8 DC 1D 00 85 C0
game.dll&H43F996_6=85 C0 0F 84 C0 00
game.dll&H3604CA_6=EB 08 C7 44 24 18
game.dll&H3A1FE4_6=8B 0C 41 66 8B 04
game.dll&H39A45B_6=8B 97 98 01 00 00
game.dll&H3A200E_7=8B 54 24 20 0F B7 32
game.dll&H3A1F63_4=75 04 A8 02
game.dll&H3A1F4E_7=E8 8D D5 C6 FF 8B D0
game.dll&H43F9A9_6=85 C0 0F 84 AD 00
game.dll&H285BFA_8=E8 B1 E2 23 00 8B 40 10
game.dll&H361EB9_7=33 C9 B8 01 00 00 00
game.dll&H74D059_6=8A 90 6C 7E AB 6F
game.dll&H39A474_8=E8 F7 7B 00 00 23 D8 89
game.dll&H285C62_5=75 29 53 8B CF
game.dll&H3CC2F2_12=74 0B 81 88 7C 02 00 00 00 02 00 00
game.dll&H3A1F69_7=8B 44 24 24 66 09 18
game.dll&H3C6E14_8=F6 D0 8A C8 8B 44 24 1C
game.dll&H752706_8=C1 E0 08 03 E8 8B 84 AE
game.dll&H285C4C_6=74 2A 8B 44 24 20
game.dll&H356FDC_8=3B 86 18 02 00 00 89 44
game.dll&HF503_9=8B 41 14 8B 49 10 BA 02 00
game.dll&H74D047_10=0F B7 0C 4A 81 C9 00 F0 00 00
game.dll&H285BF3_7=B9 0D 00 00 00 8B E8
game.dll&H361EBC_6=01 00 00 00 D3 E8
game.dll&H3A201B_4=23 CA 75 32
game.dll&H39A471_10=55 50 56 E8 F7 7B 00 00 23 D8
game.dll&H74D18C_7=E8 DF 3D FF FF 85 C0
game.dll&H39A518_6=74 27 39 6C 24 44
game.dll&H40770A_6=75 0A 83 7B 14 00
game.dll&H356D27_8=85 DB 8A 8E E8 07 00 00
game.dll&H3C6E1C_10=3D FF 00 00 00 76 05 C1 F8 1F
game.dll&H28351C_4=C3 CC CC CC
game.dll&HF540_6=74 08 8B 00 83 C4
game.dll&H3622D1_10=85 C0 0F 84 30 04 00 00 8B 03
game.dll&H39A525_13=66 85 87 F4 01 00 00 74 1D 8B 8F 98 01




&H41E237_4=74 38 A0 51
&H41E23E_16=0F BF 0D 54 EF 6C 00 0F BF 15 58 EF 6C 00 0C 01
&H41E24F_9=0F BF 35 56 EF 6C 00 A2 51
&H41E25B_10=0F BF 05 52 EF 6C 00 8D 74 06
&H4433E5_6=74 18 8B 46 0C E8
&H450236_12=8B 04 85 FC F4 68 00 83 F8 64 74 72
&H450240_6=74 72 85 C0 74 6E
&H4512E8_5=74 07 8A 43 46
&H4565E9_5=56 8B C3 E8 9F
&H4565EE_5=FE FF FF 85 C0
&H45816A_5=80 3D 3D 72 59
&H45816F_4=00 01 75 45
&H458E4A_5=80 F9 01 66 89
&H458E4F_6=15 C4 C1 68 00 5E
&H46F428_9=84 C8 0F 84 05 01 00 00 8B
&H46F42A_9=0F 84 05 01 00 00 8B 8E DC
&H47FF61_11=8A 46 07 8A A8 A0 73 59 00 03 FA
&H485BD0_9=55 8B EC 51 A1 A0 4A 65 00
&H486033_6=C3 CC CC CC CC CC
&H48A452_11=E9 E9 71 FD FF E9 54 71 FD FF C3
&H48E502_2=74 73
&H4A3357_8=A3 80 CC 59 00 E8 3F 24
&H4A3ECD_12=68 B0 DD 6C 00 FF 15 7C E3 4F 00 C3
&H4BD60F_8=E8 CC 32 FC FF E8 47 F9
&H4D302D_16=68 B0 DD 6C 00 FF 15 7C E3 4F 00 A1 F8 68 59 00


I got a PM a few days ago, asking about warden's 0x02 packet, and how i'm parseing it.
I might as well post the responce here, since I don't fancy explaining this again and again :)
I'm having some trouble translating the Get0x02Data function. My current revision should be equivalent, but I'm not matching wc3's warden output.

Could you explain what Get0x02Data is supposed to be doing? The first part appears to be checking memory offsets, but the second part makes no sense to me.

Also, how did you generate the .ini files? If I have game.dll (and other files) available, can I dynamically beat these checks?
I will explain how im parseing it, in depth, from start to finish.
This will be are example packet dump, we will be braking up/working with:

02 08 67 61 6D 65 2E 64 6C 6C 00 9F DE FF AC 88       ..game.dll......
A3 F7 06 ED 66 20 37 A9 6B BC A5 DE B3 27 B0 93       ....f 7.k....'..
0E E0 18 D2 B2 F1 00 00 2A 9F C2 22 5E 69 07 6B       ........*.."^i.k
C2 C1 5A BB C7 8C 74 5F 7C D9 9E F2 D2 9F 5C 6C       ..Z...t_|.....\l
03 80 F8 D4 06 00 30 9F 2E A1 91 55 87 F2 38 B9       ......0....U..8.
3C 44 A1 AB 67 8A 99 A9 F7 9E 9E 31 26 35 91 38       <D..g......1&5.8
F4 D7 06 00 30 9F 66 5F E0 96 5A 4C B6 FB 50 7D       ....0.f_..ZL..P}
87 01 E0 99 50 3B EC EE F1 E7 B4 EE E6 69 08 59       ....P;.......i.Y
00 00 19 53 01 8E 1E 3A 00 07 9F E9 32 09 08 D8       ...S...:....2...
FE 41 AD B2 C7 16 6A 0A 89 A0 2F 0F 34 AD 6D 9D       .A....j.../.4.m.
93 E9 15 20 50 00 00 10 E0                            ... P....

The 1st byte, 0x02, is the packet ID.
After the packet ID, you have a list of strings.
Each string has the following format:
(BYTE) String lengh
(VOID) string
As soon as you hit a string lengh of 0x00, you are at the end of the string list.
So, in the above log, the 1st string lengh is 0x08.
08 67 61 6D 65 2E 64 6C 6C "game.dll"
The 2nd string lengh is 0x00.
So, we should have now parsed the string list from the packet, and have only 1 string, "game.dll".
The string list should start at index 1, in the string list. (List[0]="", list[1]="game.dll", etc)

Now, appending the string list, you should be seeing a list of commands.
The 1st byte of each command, is a sort of 2nd level packet ID, telling you how to parse the command.
In the above example, the 1st byte following the string list, is 0x9F.
Note, this 0x9F ID will be differnt for each logon.
You should ntoice, the very last byte in the 0x02 packet, is 0xE0.
This byte was calculated from the 0x05/0x04 warden packet data.
To get the "reall" command ID, you xor the command ID with this end byte (0x9F^0xE0=0x7F)
So, we now know, the "reall" command ID for this request/command, is 0x7F.
This will remain true, for the given module. However, every module has a differnt set of ID's hardcoded into it -- so on another warden module, it maybe 0x54 for the same request/command type etc etc.
For this reason, we are not going to take notice of this command ID. We are going to do some basic pattern detection on the appending data to determin what command it really is.
At the moment, warcraft 3 and starcraft/broodwar are only useing 2 command types.
A memory check command, and a memory page check.
We know, currently, a memory check command, is 7 bytes in lengh and a page check command is 30 bytes in lengh.
I have posted the format for both checks, here.
For the memory check command, the format is:
(BYTE) String index
(DWORD) Offset/address
(BYTE) Lengh

So, is this 0x9F command a memory check command, or a page check command?
1st thing we need to do, is check if we have at least 7 bytes remaining, after are current parseing position.
In this case, we do.
Now we know theres enough bytes remaining for it to be a memory check, we need to test/compare a few values.
If the 1st byte into the command (string index) is greater than the number of strings in the string list, then this can not be a memory check.
In the above packet dump, the next byte (0xDE) is much higher than the number of strings in the list.
How ever, lets assume it did point to a valid string index.
We then check the lengh byte, to make sure it's not to high. 0x40 bytes is a good max number of bytes to go with.
Lets say for a moment, all the above checks (at least 7 bytes remaining, string index byte is inrange of the string list and the lengh of data to read byet is =< 0x40) all pass.
There is 1 more check we can do, to verify this really is a memory check command, and that is, check the offset/address dword.
If this matchs an address we know is currently been checked, and the lengh byte matchs the given address, then its safe to say this command is infact a memory check.
If we did not check the offset dword, and for ie, just read this offset from the binary, the chances of falsely identifying this command as a memory check, go up massively.

If i've confused you/over explained it, this is where we are at in the packet;
9F DE FF AC 88 A3 F7........
The code below (not compiler friendly) shows some simple checks done on this data (note; pos is the 0x9F byte, pos+1 is 0xDE etc)

//Is there enough bytes remaining in the packet, to be a memory check?
IsMem = ((pos+6) < LenghOfPacket)
//if so, does the string index byte line up with the string list?
If IsMem  Then IsMem = IsMem And (data[pos+1] <= NumberOfStrings)
//if so, check the offset, lengh and string, match a known offset/address/string
If IsMem  Then
    S = StringList[data[pos+1]] & "&H" & Hex(data[pos+2, 4]) & "_" & data[pos+6]
    select case S
        case "game.dll&H3A1DCE_7": S = "E8 5D D6 C6 FF 8B D0"
        case "game.dll&H285B3A_8": S = "E8 81 FA 22 00 8B 40 10"
        case "game.dll&H3A1E9B_4": S = "23 CA 75 32"
        case else: S= ""
    end select
    IsMem = IsMem And (len(S)>0)
    //S should now hold the memory from the given offset
    If IsMem then
    End if
End if
//Its not looking like a memory check command, unless there is a new offset that is unknown to us.
//maybe it looks like a page check command?

So, you should beable to clearly see, that the data "9F DE FF AC 88 A3 F7" fails this simple IsMemoryCheckCommand pattern detection.
(If you would like to step through these conditions compareing them with known strings/offsets/lenghs, here is a list;

game.dll&H3A1DCE_7=E8 5D D6 C6 FF 8B D0
game.dll&H285B3A_8=E8 81 FA 22 00 8B 40 10
game.dll&H743576_8=C1 E0 08 03 E8 8B 84 AE
game.dll&H361DD3_7=E8 78 F4 1C 00 85 C0
game.dll&HF453_9=8B 41 14 8B 49 10 BA 02 00
game.dll&H3C1354_8=F6 D0 8A C8 8B 44 24 1C
game.dll&H3F92CA_6=75 0A 83 7B 14 00
game.dll&H3A1E8E_7=8B 54 24 20 0F B7 32
game.dll&H285B33_7=B9 0D 00 00 00 8B E8
game.dll&H283444_7=8B C8 BA 01 00 00 00
game.dll&H39A39B_6=8B 97 98 01 00 00
game.dll&H39A458_6=74 27 39 6C 24 44
game.dll&HF490_6=74 08 8B 00 83 C4
game.dll&H73DFFC_7=E8 DF 3D FF FF 85 C0
game.dll&H361DF9_7=33 C9 B8 01 00 00 00
game.dll&H431569_6=85 C0 0F 84 AD 00
game.dll&H356F1C_8=3B 86 18 02 00 00 89 44
game.dll&H3A1DE3_4=75 04 A8 02
game.dll&H36040A_6=EB 08 C7 44 24 18
game.dll&H285BA2_5=75 29 53 8B CF
game.dll&H3A1DE9_7=8B 44 24 24 66 09 18
game.dll&H39A3B1_10=55 50 56 E8 37 7B 00 00 23 D8
game.dll&H356C67_8=85 DB 8A 8E E8 07 00 00
game.dll&H361DFC_6=01 00 00 00 D3 E8
game.dll&H39A465_13=66 85 87 F4 01 00 00 74 1D 8B 8F 98 01
game.dll&H285B8C_6=74 2A 8B 44 24 20
game.dll&H28345C_4=C3 CC CC CC
game.dll&H3A1E64_6=8B 0C 41 66 8B 04
game.dll&H356E7E_5=66 85 C0 76 04
game.dll&H73DEC9_6=8A 90 6C 68 AA 6F
game.dll&H3C135C_10=3D FF 00 00 00 76 05 C1 F8 1F
game.dll&H362211_10=85 C0 0F 84 30 04 00 00 8B 03
game.dll&H431556_6=85 C0 0F 84 C0 00
game.dll&H3A1E9B_4=23 CA 75 32
game.dll&H3C5C22_12=74 0B 81 88 7C 02 00 00 00 02 00 00
game.dll&H73DEB7_10=0F B7 0C 4A 81 C9 00 F0 00 00

So if its not a memory check command, maybe its a page check command?
Lets see!
9F DE FF AC 88 A3 F7 06 ED 66 20 37 A9 6B BC A5 DE B3 27 B0 93 0E E0 18 D2 B2 F1 00 00 2A
Do we have at least 30 bytes of data remaining in the packet?
in this case, we do.
Based on the format posted here, is the last byte (lengh byte) <= 0x80?
0x2A is =< 0x80, so yes!
Is the 2nd from last byte equal to 0x00?
0x00 = 0x00, so yes!
Is the 3rd from last byte <= 0x40?
0x00 is =< 0x40, so yes!
Now lets check the last 4 bytes and compare it with a list of known values, to make sure.


F1 00 00 2A is = &H2A0000F1, so yes!
We know its probly not a memory check, but it looks like a known page check.

Now we know this is a page check, we move the position up 30 bytes, to the next command.
You should notice, these are the actual commands;

9F DE FF AC 88 A3 F7 06 ED 66 20 37 A9 6B BC A5 DE B3 27 B0 93 0E E0 18 D2 B2 F1 00 00 2A
9F C2 22 5E 69 07 6B C2 C1 5A BB C7 8C 74 5F 7C D9 9E F2 D2 9F 5C 6C 03 80 F8 D4 06 00 30
9F 2E A1 91 55 87 F2 38 B9 3C 44 A1 AB 67 8A 99 A9 F7 9E 9E 31 26 35 91 38 F4 D7 06 00 30
9F 66 5F E0 96 5A 4C B6 FB 50 7D 87 01 E0 99 50 3B EC EE F1 E7 B4 EE E6 69 08 59 00 00 19
53 01 8E 1E 3A 00 07
9F E9 32 09 08 D8 FE 41 AD B2 C7 16 6A 0A 89 A0 2F 0F 34 AD 6D 9D 93 E9 15 20 50 00 00 10

The 1st 4 are clearly page check commands, the 5th is a memory check command, and the 6th is another page check command.
So, for building the responce to these, we give the all clear for the 1st 4 page checks.
Are responce data is now, "00 00 00 00" (4x all clears)
We now append the "success on reading memory" for the memory check command, as well as it's related memory chunk.
So the responce data should now be "00 00 00 00" + "00 8B 54 24 20 0F B7 32"
We then give the all clear for the last page check, giving us "00 00 00 00 00 8B 54 24 20 0F B7 32 00"

Now we have the responce data for the above 0x02 packet, we SHA1 this data with wardens SHA1 function and xor each of the resulting dwords together.
This should give us "D5 32 D1 02".
The lengh of the responce data is 0x0D bytes.
And that makes up are responce 0x02 packet;
(BYTE) packet ID 0x02
(WORD) lengh of responce data 0x0D
(DWORD) hash of responce data 0x02D132D5
(VOID) Responce data "00 00 00 00 00 8B 54 24 20 0F B7 32 00"

02 0D 00 D5 32 D1 02 00 00 00 00 00 8B 54 24 20       ....2........T$
0F B7 32 00                                           ..2.

Now, if by chance, it fail's these pattern checks, it's more than likely that the memory check/page check offsets/lenghs have been changed.
So, you're probly wundering, how do you get these new offsets and their related memory blobs?
Well, for memory checks, the memory returned can be found at the strings base address+offset, or if the string is empty (string index 0x00) then the offset is a base address.
For example, the memory check "53 01 8E 1E 3A 00 07"
the string index points to the string "game.dll"
If you open up game.dll, and go to the address 0x003A1E8E and look at the following 7 bytes, you will see the data "8B 54 24 20 0F B7 32"
This is the memory that is returned to battle.net.
When these offsets change, I takes around 5mins, to check and double check the offsets and get the related memory data to add to a new list.
IMO, it's safer go over the packets manualy a few times, and build a list.
This way, you can identify changes to the protocol and most of all, have peace of mind.

This is just one of many ways you can parse this packet.
I figured, releaseing code that works in this way, would be the most easyest to understand and probly the most fail safe.

If anyone wants to add to the above (i've probly over explained a few things or missed a few things) or doesnt understand somthing, feel free to ask and I will add to and/or correct the above.
I saw a photo of a lightning bolt streeking acoss the nights sky and thought it looked cool!
So I thought what the hell, I would try to make some lightning bolts in vb6, useing nothing more than afew buffer's and make the math up as I go alone, on each pixel. Since I suck at math, it prooved pretty hard to pull off :(

Here's some images/animations/video files, showing where I started at, LoL bugs, and where i'm at now.
Tell me what ones you like best, what you think needs changing, etc etc.

Ok so I started with a "waypoint" consept, since any other way of doing it I was thinking up, involved added almost all known laws of phyisics to the project :P
Figured, might as well keep it simple.

Then I tryed adding *splits*, so a lightning bolt would split into multiple smaller bolts. This went tits up 1st attemp and split into a few to many.

Then I tryed to fix it, and it literly went super nova/blew up in my face :o

After I got that working abit better, I set up a block of floating point variables to be the "image data", so I could do small calculations on each R, G, B and A values, then round them off to a RGBA byte based buffer after each update, to be dumped to file along with a bitmap file/info header.
For 1st attempt at the graphic, I was pretty impressed, altho it was abit square shape.

So, I tryed to make the image abit better, by adding some back ground lighting effect, as the sky would light up as nitrogen reflects the white light, as blue light.
This had a halow effect, close to the bolt :(
MultiStrike.avi.zip 1 second video clip of this style, 1 frame per 5 updates, 50fps.

So I expanded on this halow effect to see if it would work as background lighting

Then I spent most of aday rewriteing it, trying all kinds of things, to stop multiple bolts *white* burning each other, and background lighting effects refuseing to blend with out a small noticeable seam.
I could get 1 or the other, but not both :/
So, I just started fucking around with it today, and reverted back, with some minor tweeks here and there;

And heres a high_def_annimation.mng of one, just this morning. Its 1 frame every 5 updates.

Persionaly, I like this one the best and the still image just above this.
(The only above has better background lighting/shadeing imo)

What about you?
General Discussion / Window's acting strange
May 09, 2009, 12:49 PM
I'm just wundering if anyone else has had things like this happen in the past, and if so, what was the problem :p
I think I might have a computer virus or somthing. :(
I've rebooted my computer once, since I noticed these things start happening.

A) I'm signed out of all web pages and have to sign in manualy. This happens again, after a reboot.
B) After rebooting, windows taskmanager no longer displays the "user name" string along side the image name -- it's blank, apart from the "system idle process" having the user name "SYSTEM"
C) I can no longer watch .mp4 video files -- say's I dont have the required codecs on the system, but I do, or did.
D) When ever I try bind() a UDP socket, vb6 always raises run time error 18.

Any ideas?
I'm running a full AV scan atm, but it's going to take all day :(
StarCraft / Battle report #2
April 22, 2009, 05:30 AM
Besides the cheesy commentry, and a couple of noobs trying to do stuff pro-gamers do on broodwar, I thought zerg looks pretty neat :)
Besides the zerglings moving like froglings :d
Battle.net Bot Development / BNLS_WARDEN? (0x7D)
April 17, 2009, 08:27 AM
I've been running a BNLS server for some time now, mainly so I can update one program rather than updating countless bot's.
I was trying to talk Hdx into adding the packet into JBLS awhile back, and he thought I should post the packet spec here, to get ideas/feed back.
Altho im pretty sure each useage contains enough infomation to support predictible changes to warden in the future, they are open to suggestions. :p
All of the below is already in existance, but if you can think of more useages, more variables to include, or ideas in general, please post them!.

I've spent a few hours writeing up some protocol spec below, but im not to good at explaining things, so feel free to ask about anything that I haven't explained very well.

note: I used 0x7D, as it was well into no-mans-land, since I didn't want to step on skywings/yoni's toes, if or when they ever pick up on the orginal BNLS project and start adding new packets (for sc2/d3 maybe) :p

BNLS_WARDEN (packet 0x7D);
C>S Format:

    (BYTE)     Useage
    (DWORD)    Cookie
    Useage 0x00 (Warden Seed)
        (DWORD)    Client
        (WORD)     Lengh of Seed
        (VOID)     Seed
        (STRING)   Username (blank)
        (WORD)     Lengh of password
        (VOID)     Password
    Useage 0x01 (warden packet)
        (WORD)     Lengh Of Warden Packet
        (VOID)     Warden Packet Data
    Useage 0x02 (warden 0x05)
        (DWORD)    Client
        (WORD)     Lengh Of Seed
        (VOID)     Seed
        (DWORD)    Unused
        (BYTE[16]) Module MD5 Name
        (WORD)     Lengh of Warden 0x05 packet
        (VOID)     Warden 0x05 packet
    Useage 0x03 (warden checks/ini file)
        (DWORD)    Client
        (DWORD)    Info Type (0x01)
        (WORD)     Unused (must be 0x00)
        (VOID)     Unused

S>C Format:

    (BYTE)     Useage
    (DWORD)    Cookie
    (BYTE)     Result
    (WORD)     Lengh of data
    (VOID)     Data

BNLS_WARDEN can currently support 2 methods for SC/BW/W3ROC/W3TFT.
The first method (useage 0x00 and 0x01) allows you to support warden over battle.net with out any need for installing warden related code and algorithm.
- It does how ever, require you stay connected to the server, or at least, connect each time a new request comes in from bnet.
The second method (useage 0x02 and 0x03) allows you to support the more basic side of warden, why leaving all the more complex things to the BNLS server.
- One side to this method, allows you to support warden, with out having to worry about downloading, loading and executeing warden modules, from bnet.

A basic description of the packet values above;
The useage byte, tells the BNLS server how to parse you'er request.
- 0x00 Is for initializeing a new bnet connection, to allocate a packet handler for you, on the server.
- 0x01 Is for having you're warden requests handled, via the pre allocated packet handler, done in useage 0x00.
- 0x02 Is for getting the correct data in responce to warden 0x05 and a new set of RC4 keys -- as well as any other future module requireing packets.
- 0x03 Is for getting a list of offsets and their contents, to be used in you're warden 0x02 handler.
The cookie is sent back to the client, to identifying one request from another.
- With useage 0x01, this value must remain the same as the one you initialized for a given bnet connection, with useage 0x00.
- Its important to use differnt cookies for differnt bots when dealing with useage 0x00 and 0x01, so not to have a RC4 cryption keys currupted and have to reconnect to bnet.
- For more info on useage 0x00/0x01 cookies, see the "First Method" description below.
The client value identifys what client you connected to bnet with.
- It can be the DWORD you use over bnet (Ie; PXES) or one of the below;
- 0x01 = Starcraft
- 0x02 = Broodwar
- 0x03 = Warcraft 2
- 0x04 = Diablo 2
- 0x05 = Diablo 2 LOD
- 0x06 = Starcraft Japan
- 0x07 = Warcraft 3
- 0x08 = Warcraft 3 TFT
- 0x09 = Diablo
- 0x0A = Diablo SWare
- 0x0B = Starcraft SWare
The seed value, is used to initialize wardens cryptography.
- Currently, This value should be the 1st DWORD of the first CDKey hash, in C>S 0x51.
- For now, only a 4 byte seed is acceptable.
- Note* If you are useing the older logon protocol (BNCS 0x06, 0x07, etc), this seed value should be zero.
The Module MD5 Name is obtained from the warden 0x01 packet, starting at the 2nd byte.
The username and password, are for possible future updates.
- They can be ignored, for now.
- Just leave the user name blank, and the lengh of password to zero.
For the result value in the responce, see the "Result values and meanings" description below.

First Method (useage 0x00 and 0x01)
This connection style, allows you to support warden over battle.net with out any need for installing warden related code and algorithms into you're program.
It does how ever, require you stay connected to the server, or at least, connect each time a new request comes in from bnet.
This is basicly, A fully managed remote warden handler.
The Cookie value is used to allocate (useage 0x00) and access (useage 0x01) a warden connection/handler.
Once you init a cookie (useage 0x00), it can then be sent back to BNLS with a bnet warden packet (useage 0x01) to have the request handled, and a responce sent back to you to be sent on to bnet.
You can manage multiple bnet connections/wardens via 1 or more BNLS sockets.
Useage 0x00:
When Logging onto battle.net, and building you're C>S 0x51 packet, you need to obtain the first dword of the first cdkey hash. This is the seed value used in useage 0x00.
You then send this seed value to BNLS, via useage 0x00, to activate, or reset then given cookie.
This cookie value must be differnt from any other bots useing the same BNLS server from you're network, so not to cause clashs's.
The BNLS server will respond telling you if the cookie was successfully initialized or not.
The data in the responce should only ever be present if the responce contains an error code.
Useage 0x01:
Once you have successfully initialized a cookie for a bnet connection, you are ready to faward all bnet warden traffic to BNLS.
If the result comes back with an error code, the "Warden Packet Data" may contain infomation about the given error code.
If the result comes back successfull, the the "Warden Packet Data" will contain the BNCS 0x5E payload to be sent to bnet.
you should only send the responce data to bnet if the request was successfull, the lengh of the data is 1 or more and its a 0x01 useage responce.
Note, after initing a cookie with useage 0x00, that space will remain allocated on the server, for up to 3mins.
This allows you to reconnect, and still beable to resume where you left off, with out having to reconnect to bnet.
You should only send the PAYLOAD of the S>C BNCS 0x5E warden packet, and NOT the full BNCS packet.

Second Method (useage 0x02 and 0x03)
This allows you to manage you're own warden handler, and avoid the need to download and manage warden modules from battle.net.
Useage 0x02:
This is for manageing packets that only the downloaded warden module's can do.
Currently, warden sends you an 0x05 packet that's used to verify you're truely running the correct warden module.
You can send the whole decrypted 0x05 packet (including the packet ID) and get the 0x04 Responce and new set of RC4 keys.
Since the algorithm warden uses to generate the 0x04 responce data is differnt in each downloaded module, this useage requires you also send you're orginal seed and the module name.
It's possible, in the future, more module requireing packets, such as 0x05, may come into play.
Because of that, the data in the responce to useage 0x02 maybe variable.
This is the current supported format for the "data" in useage 0x02 responces;

(DWORD)    Responce Type
Type 0x01:
    (BYTE[258]) New RC4In Key
    (BYTE[258]) New RC4Out Key
    (DWORD)     Lengh Of warden Responce
    (VOID)      Warden responce packet Data

The warden responce packet data, currently, will be the whole raw 0x04 packet.
You then encrypt the responce packet data with you're existing rc4out key, then replace you're existing RC4 key's with the new ones.
It's possible, at times, the BNLS server may respond with the result code 0x03 (warden module not loaded).
There is a short delay between bnet switching to a new warden module and the BNLS server downloading it from bnet, so try again in 10 or more seconds.
Useage 0x03:
This is allows you to download a file and/or infomation about the checks warden is making. This infomation can be used by you're warden 0x02 parser to identify the check type and it's result.
Currently, only info type 0x01 is supported. (downloading of a .ini file)
The "data" in the responce to useage 0x03, has the following format:

(DWORD)    Into type
For type 0x01:
    (DWORD[2]) File time
    (VOID) ini file data

It may, in the future, support more info types, depending in what direction warden goes.

Result values and meanings
The result code, in the responce, maybe one of the following;
0x00 = Success
0x01 = Unable to find you're allocated packet handler.
- This is used in useage 0x00 and 0x01 responces.
- Useage 0x00: it normaly means the BNLS server has reached it's designated limit. In a nut shell, the server is full.
- Useage 0x01: The cookie  was not initialized with useage 0x00, Or you're cookie has timed out/removed,
0x02 = Incoming Data currupt
- This is used in useage 0x01, telling you that the incomming warden data was unreadable, after decryption.
0x03 = warden module is not loaded yet
- Bnet has switched to another module and this BNLS server does not have it yet.
- It should automaticly update (get the new module) anywhere from 10 seconds, to 10mins -- try again later.
0x04 = error executing warden module
- BNLS was unable to load and/or execute the given warden module.
- Basicly, shit hit the fan.
0x05 = Unsupported bnet client/game
- You're bnet client/game is unsupported.
- Currently supports starcraft and warcraft III BNCS warden, but may enable D2/D2LOD D2GS warden in the future.
0x06 = Warden hack check error
- The BNLS server was unable to read the warden 0x02 packet.
0x07 = Warden check invalid
- The offsets have probly changed and the BNLS server is not yet aware.
0x08 = incomming warden packet unsupported
- This is used with useage 0x02.
- Currently, only warden packet 0x05 is supported.
0x09 = unsupported warden info type
- This is used with useage 0x03.
- BNLS is not yet able to process this info type.
- Currentl supported info types are: 0x01
0xFD = Invalid password
0xFE = Invalid user name
- This is used with useage 0x00.
- Currently, that method is open for all to use. (leave user name and password as blank strings)
- In the future, if the sevrer is being abused, it maybe required of you, to use a BNLS username and password.
0xFF = You're request was currupt.
- You're BNLS 0x7D packet had bad format, or sizes.
- The "data" in the responce, may contain an offset into you're packet, where the problem is.
General Discussion / Woops
January 05, 2009, 01:05 AM
Maybe this is why my comp keeps randomly rebooting? :p

cpu was at 55c
hmm, I got bored again :p
I read HDX's post in the C++ forum, and it got me thinking:
Since I wrote an ASM class for vb6, I thought id see how fast I could really get VB6 CheckRrevision moving!
Ive been comparing it with BNCSutli.dll, and got it moving 2 times as fast :)
I'm posting it here incase anyone want's to add it to their bot.
You can download the test project here: VB6Checkrevision.zip
You will need to paste Warcraft3 binary's into the same directory as the project, since they are not included in the zip.
Here's some out put's compared to BNCSutli.dll's:

VB6 Check revision:
   Time     = 93ms
   Checksum = 0xB268CECB
   Version  = 0x11600B8
   Info = war3.exe 08/19/08 12:58:06 471040

C++ Check revision:
   Time     = 203ms
   Checksum = 0xB268CECB

The project/code is abit of a mess, so you might want to clean it up before useing it.
1 Main advantage of this, is it runs just as fast in debug mode, as it does compiled!
All suggestions are welcome, but please note: I know the code is a mess ;)
Fun Forum™ / How to self pwn you're self on Bnet!
December 16, 2008, 01:33 PM
Ok, so a little desc of how I self pwned my self today:
I run a D2 bot for the mass's, so they can level up, leach items etc.
Have run a public game runner for the mass's for a few years now, even tho I dont play d2.
I added full new-warden support to it about a week ago.
Today, I got the error "Character not found", even tho my character is still on the main screen..
So, I wrote a email to blizzard about it, playing the legit guy.

Quote from: martyt.support@blizzard
Hello Rob,
Thank you for contacting Blizzard Entertainment.

We have checked your character and attempted to repair the reported issue. Regrettably, our attempts to repair the character were unsuccessful.
With any character corruption, an attempt to restore the character to a previous date before the corruption occurred is made.
In this case our attempts did not repair the issues affecting the character.
The affected character will unfortunately no longer be able to be used in-game. We sincerely apologize for the loss of the character, and any inconvenience this has caused you.
The character will remain on the character selection screen until manually deleted.
If there is anything else I can do to assist you, please don't hesitate to contact me at: MartyT.Support@Blizzard.com.
Marty T.

So, me trying to act like any legit player would when they lost a lvl 99 account, I replyed with a little pretend rant, hoping to probe more info:
Quote from: Ringo
omg really? :((((
He was lvl 99!!!!
I spent months playing him and now he is gone?
Now I have no items... no character.. no nothing :(
Are you sure it's not possible to repair him?
And if I spend months of my life making another character, what's to say the same thing wont happen again?
I guess, more to the point, why did this happen in the first place?
Sry if I sound angry, but.. i'm angry :(
Plz respond, thanks.
I should be an actor, yeah?! ok maybe not.
Anyway, he replyed with this:
Quote from: martyt.support@blizzard
Hello Rob, When I can't repair a character, it's usually due to corruption from utilizing third party programs or bots.
I suggest you remove any you might be using.
The affected character will unfortunately no longer be able to be used in-game.
We sincerely apologize for the loss of the character, and any inconvenience this has caused you. 
The character will remain on the character selection screen until manually deleted.
If there is anything else I can do to assist you, please don't hesitate to contact me at:[email protected].
Marty T.

Now for the part where I totaly self pwned my self.
Why this email convo with marty was going on, I was chatting away on bnet:
[18:33:48] <Ringo> supprised he didnt check the character stats
[18:34:01] <Ringo> "WTF 1 week bnet logged in time, 7 months ingame time?"
[18:34:20] <Noob_tHiEF> lol
[18:34:59] <Noob_tHiEF> kinda works like the SC cross server gaming?
[18:35:28] <Ringo> nah lol
[18:35:39] <Ringo> my d2 bots connect to bnet, query the realm, logon the realm, then disconnect from bnet
[18:35:48] <Noob_tHiEF> ahh
[18:35:52] <Ringo> then play a bunch of games on realm, and do all again when they switch cdkey
[18:35:59] <Ringo> so it never really enters bnet chat before it discs :)
[18:36:11] <Ringo> probly hasnt even 1 week logon time tbh
[18:36:25] <Ringo> only the time ive spent muleing manualy on d2 lol
[18:37:29] <Ringo> feking blizzard tbh
[18:37:37] <Ringo> I have like another 20 palas i could run on bot
[18:37:46] <Ringo> but a) the same thing could happen to them
[18:37:52] <Ringo> and b) they dont have dindin in their names
[18:37:59] <Noob_tHiEF> lol
[18:38:31] <Ringo> plus none of them have the correct items :p
[18:38:49] <Ringo> and my d2 jsp acc got disabled, so i dont have anything to trade with, unless i start up all my d2 bots again *sigh*
[18:38:53] <Noob_tHiEF> why did the char fuck up?
[18:39:19] <Ringo> no idea
[18:39:25] <Ringo> I think its a rare bug their end
[18:39:41] <Ringo> very rarely, when the character file is saving, somthing fucks up and currupts it
[18:45:10] <Ringo> oh oh, i got a responce from martyT about my pretend moaning
[18:45:43] <Ringo> When I can't repair a character, it's usually due to corruption from utilizing third party programs or bots. I suggest you remove any you might be using.
[18:45:45] <Ringo> LOL
[18:45:49] <Ringo> ME?
[18:45:54] <Ringo> BOTS?
[18:46:01] <Ringo> HES ON FING DUGS?
[18:46:48] <Noob_tHiEF> lol
[18:47:18] <Ringo> I get the feeling hes seen my logon log times
[18:47:44] <Ringo> none the less, I still cant see how, a bot can currupt the server side save file
[18:47:48] <Ringo> umm
[18:48:06] <Ringo> but how do I say that to him with out blatently admitting im running hax lol
[18:48:19] <MartyT.Support@Blizzard> it's a bit too late for that....
The bastard was in the channel all along! LOL :D
What can I say in my defense now?
I got bored, so I started porting iagos module preperation code from here:
I havent spent much time on this yet, so i'm still alittle unsure of a few things.
Mainly, how do you calculate the base address of the function with in a given warden module, for handleing the packets?
I noticed in iagos notes, hes talked of Maive_HandleWardenPacket()
Should these function tables be generated when loading the module, or does the module its self allocate the memory for them?
http://www.skullsecurity.org/wiki/index.php/My_notes "WardenFunctionList @ WardenUnknownPtr1"

So far i'm able to prep the module, load it into memory and initialize it.
Ive noticed when I do this, the function table I pass to it, get's a few callbacks to allocate memory. I haven't looked at these memory spaces yet, but are any of them a list of exportable warden function address'?
Basicly, what i'm wanting to do, is load the module, pass it the 1st request(0x05) and get the responce(0x04) and the new RC4 keys, then unload it.
Heres the output I currently have: (Code is below)

   Allocated 49152 (0xC000) bytes for new module
   Copying code sections to module.
   Adjusting references to global variables...
   Updating API library references..
   Lib: KERNEL32.dll
       Function: Sleep
       Function: TlsGetValue
       Function: TlsSetValue
       Function: RaiseException
       Function: GetProcAddress
       Function: GetModuleHandleA
       Function: TlsAlloc
       Function: TlsFree
       Function: GetVersionExA
       Function: VirtualQuery
       Function: QueryDosDeviceA
       Function: GetTickCount
       Function: GetSystemInfo
       Function: GetCurrentProcess
       Function: LoadLibraryA
       Function: DuplicateHandle
       Function: CloseHandle
       Function: FreeLibrary
       Function: GetProcessHeap
       Function: HeapFree
       Function: TerminateProcess
       Function: UnhandledExceptionFilter
       Function: SetUnhandledExceptionFilter
       Function: QueryPerformanceCounter
       Function: GetCurrentThreadId
       Function: GetCurrentProcessId
       Function: GetSystemTimeAsFileTime
       Function: RtlUnwind
   Lib: USER32.dll
       Function: CharUpperBuffA
       Function: DestroyIcon
       Function: RegisterClassA
   Successfully mapped Warden Module to 0x3467678
   Initialize Function is mapped at 0x346A858
   Calling Initialize function and passing my callback function table
Warden.AllocMemory() 2020
Warden.AllocMemory() 52
Warden.AllocMemory() 44

You can see it allocates 2020 bytes, 52 bytes and 44 bytes -- are thses possibly some exportable functions?
I noticed I had to allocate the memory my self, and return it to the module, other wise it gets stuck. (or w/e)

Here's the visual bitch 6.0 code, for anyone whos interested in this:
(Yes, it's a hell of a mess atm)

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long)
Private Declare Function LoadLibraryA Lib "kernel32" (ByVal strFilePath As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub CallFunc Lib "Warden" Alias "#2" (ByVal Address As Long, ByVal dwParam As Long)
Private Declare Function AllocMem Lib "Warden" Alias "#1" (ByVal dwSize As Long) As Long
Private Declare Sub FreeMem Lib "Warden" Alias "#3" (ByVal dwMem As Long)

Public Function PrepareModule(ByRef pModule As Long) As Long
    Debug.Print "PrepareModule()"
    Dim dwModuleSize        As Long
    Dim pNewModule          As Long
    Dim hMem                As Long
    dwModuleSize = getInteger(pModule, &H0)
    hMem = GlobalAlloc(0, dwModuleSize)
    pNewModule = GlobalLock(hMem)
    Debug.Print "   Allocated " & dwModuleSize & " (0x" & Hex(dwModuleSize) & ") bytes for new module"
    Call CopyMemory(ByVal pNewModule, ByVal pModule, 40)
    Dim dwSrcLocation       As Long
    Dim dwDestLocation      As Long
    Dim dwLimit             As Long
    dwSrcLocation = &H28 + (getInteger(pNewModule, &H24) * 12)
    dwDestLocation = getInteger(pModule, &H28)
    dwLimit = getInteger(pModule, &H0)
    Dim bSkip               As Boolean
    Debug.Print "   Copying code sections to module."
    While (dwDestLocation < dwLimit)
        Dim dwCount         As Long
        Call CopyMemory(ByVal VarPtr(dwCount), ByVal pModule + dwSrcLocation, 1)
        Call CopyMemory(ByVal VarPtr(dwCount) + 1, ByVal pModule + dwSrcLocation + 1, 1)
        dwSrcLocation = dwSrcLocation + 2
        If (bSkip = False) Then
            Call CopyMemory(ByVal pNewModule + dwDestLocation, ByVal pModule + dwSrcLocation, dwCount)
            dwSrcLocation = dwSrcLocation + dwCount
        End If
        bSkip = Not bSkip
        dwDestLocation = dwDestLocation + dwCount
    Debug.Print "   Adjusting references to global variables..."
    dwSrcLocation = getInteger(pModule, 8)
    dwDestLocation = 0
    Dim i                       As Long
    Dim lng0x0C                 As Long
    Dim lngTest                 As Long
    Call CopyMemory(lng0x0C, ByVal pNewModule + &HC, 4)
    While (i < lng0x0C)
        Call CopyMemory(lngTest, ByVal pNewModule + dwSrcLocation, 1)
        lngTest = lngTest And &HFF&
        Call CopyMemory(ByVal VarPtr(lngTest) + 0, ByVal pNewModule + dwSrcLocation + 1, 1)
        Call CopyMemory(ByVal VarPtr(lngTest) + 1, ByVal pNewModule + dwSrcLocation, 1)
        dwDestLocation = dwDestLocation + lngTest
        dwSrcLocation = dwSrcLocation + 2
        Call insertInteger(pNewModule, dwDestLocation, getInteger(pNewModule, dwDestLocation) + pNewModule)
        i = i + 1
    Debug.Print "   Updating API library references.."
    dwLimit = getInteger(pNewModule, &H20)
    Dim dwProcStart             As Long
    Dim szLib                   As String
    Dim dwProcOffset            As Long
    Dim hModule                 As Long
    Dim dwProc                  As Long
    Dim szFunc                  As String
    For i = 0 To dwLimit - 1
        dwProcStart = getInteger(pNewModule, &H1C) + (i * 8)
        szLib = GetSTRING(pNewModule + getInteger(pNewModule, dwProcStart))
        dwProcOffset = getInteger(pNewModule, dwProcStart + 4)
        Debug.Print "   Lib: " & szLib
        hModule = LoadLibraryA(szLib)
        dwProc = getInteger(pNewModule, dwProcOffset)
        While dwProc
            If (dwProc > 0) Then
                szFunc = GetSTRING(pNewModule + dwProc)
                Debug.Print "       Function: " & szFunc
                Call insertInteger(pNewModule, dwProcOffset, GetProcAddress(hModule, szFunc))
                dwProc = dwProc And &H7FFFFFFF
                Debug.Print "       Ordinary: 0x" & Hex(dwProc)
            End If
            dwProcOffset = dwProcOffset + 4
            dwProc = getInteger(pNewModule, dwProcOffset)
    Next i
    Debug.Print "   Successfully mapped Warden Module to 0x" & Hex(pNewModule)
    PrepareModule = pNewModule
End Function

Public Function InitializeWarden(ByRef pModule As Long) As Boolean
    Debug.Print "InitializeWarden()"
    Dim ECX             As Long
    Dim EDX             As Long
    Dim EBP             As Long
    EBP = getInteger(pModule, &H18)
    EDX = 1 - EBP
    If (EDX > getInteger(pModule, &H14)) Then Exit Function
    ECX = getInteger(pModule, &H10) 'offsetWardenSetup
    ECX = getInteger(pModule, ECX + (EDX * 4)) + pModule
    Debug.Print "   Initialize Function is mapped at 0x" & Hex(ECX)
    Dim F(6)    As Long
    F(0) = Addr2Ptr(AddressOf SendPacket)
    F(1) = Addr2Ptr(AddressOf LoadModule)
    F(2) = 0&
    F(3) = Addr2Ptr(AddressOf AllocMemory)
    F(4) = Addr2Ptr(AddressOf FreeMemory)
    F(5) = Addr2Ptr(AddressOf SetRC4Data)
    F(6) = Addr2Ptr(AddressOf GetRC4Data)
    Debug.Print "   Calling Initialize function and passing my callback function table"
    Call CallFunc(ECX, VarPtr(F(0)))
    InitializeWarden = True
End Function

Private Sub SendPacket(ByVal pPacket As Byte, ByVal dwSize As Long)
    Debug.Print "Warden.SendPacket() " & dwSize
End Sub
Private Sub LoadModule(ByVal A As Long, ByVal B As Long)
    Debug.Print "Warden.LoadModule() " & A & "/" & B
End Sub
Private Function AllocMemory(ByVal dwSize As Long) As Long
    AllocMemory = AllocMem(dwSize)
    Debug.Print "Warden.AllocMemory() " & dwSize
End Function
Private Sub FreeMemory(ByVal dwMemory As Long)
    Call FreeMem(dwMemory)
    Debug.Print "Warden.FreeMemory() " & dwMemory
End Sub
Private Sub SetRC4Data(ByVal lpKeys As Long, ByVal dwSize As Long)
    Debug.Print "Warden.SetRC4Data() " & lpKeys & "/" & dwSize
End Sub
Private Sub GetRC4Data(ByVal lpBuffer As Long, ByVal dwSize As Long)
    Debug.Print "Warden.GetRC4Data() " & lpBuffer & "/" & dwSize
End Sub

Private Function getInteger(ByRef bArray As Long, ByVal dwLocation As Long) As Long
    Call CopyMemory(getInteger, ByVal bArray + dwLocation, 4)
End Function
Private Sub insertInteger(ByRef bArray As Long, ByVal dwLocation As Long, ByVal dwValue As Long)
    Call CopyMemory(ByVal bArray + dwLocation, dwValue, 4)
End Sub
Private Function GetSTRING(ByRef bArray As Long) As String
    Dim bTest           As Byte
    Dim i               As Long
        Call CopyMemory(bTest, ByVal bArray + i, 1)
        If (bTest = 0) Then
            If (i = 0) Then Exit Function
            GetSTRING = String(i, 0)
            Call CopyMemory(ByVal GetSTRING, ByVal bArray, i)
            Exit Function
        End If
        i = i + 1
End Function
Private Function Addr2Ptr(ByVal lngAddr As Long) As Long
    Addr2Ptr = lngAddr
End Function

And heres the functions I compiled to a DLL to mainly call the init function, since its __fastcall and a bitch to call from a vb class:

typedef VOID (__fastcall *Function4)(DWORD* lpPtr);

DllExport VOID __stdcall CallFunc(DWORD Func, DWORD Value)
    Function4 test = (Function4)Func;
    DWORD dwTable = Value;

DllExport LPVOID __stdcall AllocMem(DWORD dwSize)
    return malloc(dwSize);

DllExport VOID __stdcall FreeMem(LPVOID lpMemory)

PrepareModule() takes the memory address of the module after its decrypted/decompressed etc, and returns an address of the preped module.

Any ideas?
thx in advance!
Battle.net Bot Development / Sound's of battle.net?
November 14, 2008, 08:57 AM
I got reall damn bored (I mean REALLY) so I started thinking of somthing to do.
You know, not somthing you want to comit to, but somthing really.. retarded and random. :p
Then I started to think about how most media players, when playing just audio, generate graphical patterns based on the sound.
So then I thought, why not generate sound patterns, based on graphical data?
Why graphical data, why not network data? why not bnet data? Perfect! The idea is random and retarded, I couldn't seriously comit to such a project.
With the critierias met, I started wundering on how to generate such wave patterns, and what parts of bnet traffic should seed them etc etc.
But before I jump into the deep end, I thought I would have a play around with the with the kernel beep() function and feed bnet traffic into it, to see what kind of tones it would generate.
Infact, I have a bot running in the background why i'm typeing this post, and I must say, its annoying to listen to -- it's like a 56k modem on smack.. in a retarded way ofc. Each packet has a more less unique array of beeps :p

If you're REALLY*100 suffering from bordom and wanna listen to the *sounds of bnet*, the code is below:

Every time you send or recv a packet, pass the data to the AddBeepData() sub.
Put a timer on the form, set it to 1ms interval and call PlayBeep()

Private Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long

Private m_Data          As String
Private m_Pos           As Long

Public Sub AddBeepData(ByRef S As String)
    m_Data = m_Data & S
End Sub

Public Sub PlayBeep()
    Dim B       As Integer
    If Len(m_Data) = 0 Then Exit Sub
    B = PullBeep()
    Beep B, 1
End Sub

Private Function PullBeep() As Integer
    Dim i       As Integer
    Dim B       As Long
    For i = 1 To (Len(m_Data) / 20) + 1
        m_Pos = m_Pos + 1
        If m_Pos > Len(m_Data) Then: m_Data = vbNullString: m_Pos = 0: Exit For
        B = B + Asc(Mid$(m_Data, m_Pos, 1))
    Next i
    If m_Pos > 1024 Then
        m_Pos = 0
        m_Data = Mid$(m_Data, 1026)
    End If
    PullBeep = 500 + ((B / i) * 8)
End Function

Think it would be annoying, to have sound patterns generated from bnet data, like when ppl talk etc -- giving each persion a unique sound/music plus speach sound/music?
Or, would it be retardedly fantastic option to have a bnet chat bot?

should of probly posted this in the fun forum, or the trash can -- was ment as humor :p
umm, yeah. After posting that SC mini map code, and a few pms i got, I figgerd ppl were interested in this. So I started writeing an open source client over the weekend (been a long weekend :()
Lately ive been writeing a SCGP class, one thats copy/paste friendly that can be added to any vb project, and work -- some kind of base to modify, depending what i feel like doing on the day.
The class is only about 20% finished -- but it can host games, join games, download and upload maps, chat with players -- pretty much everything game room related.
See below for infomation about SCGP class, how to use it, and the event's it returns.

As for this open source client, you can download it here: SCGP.zip
If you're wundering what it is, heres a few screen shots of it:

Ive also included an executable, so even if you don't have VB, you can play around with it.
Given the time I found to write it, the code is pretty messy and some of my home made control class's are.. well, in a word.. shit. However, it should be a good example, which is all I really had in mind (Just went abit OTT, you know.. as you do) :(
Anyway, Enjoy!

As for the SCGP class:
You can view it here: clsSCGP.cls
It requires you have a version of storm.dll in the project directory. I Find storm.dll version to be most stable.
1st of all, you MUST *update* the class, every 250ms, other wise it will be about as active as a 20 stone woman in bed.
So basicly, just have a timer with an interval of 250ms, and in the timer() sub, call the SCGP.update sub.
This will allow it to track time (even tho, that is at best, very basic at the moment)
You MUST also pass UDP data to the class via SCGP.OnData(Data, IP, Port)

Now, lets say you want to join a game:
You need to pass the class a few things to get the ball rolling.
You need the following infomation:

lngIP = inet_addr("")
intPort = htons(6112)
MyAcc = "Ringo"
MyStats = "PXES 0 0 0 0 0 0 0 0 PXES"
Password = ""
Handle = sckUDP.SocketHandle

Call SCGP.InitJoin(lngIP, intPort, MyAcc, MyStats, Password, Handle)

As for creating a game, you need abit more infomation for this.

Handle = sckUDP.SocketHandle
MPQ = app.path & "\(8)Big Game Hunters.scm"
intGameType = &HF 'top vs bottom
intPenalty = 1 '7v1
MPQHash = GetFileTimeHash(MPQ) 'get the hash from the file time or w/e u put it
lngStatsCode = &H0 'melee stats
lngMyClient = &H53455850 'PXES
MyAcc = "Ringo"
GameName = "Lets Stomp Comps"
GamePass = ""
GameSpeed = 6
GameStats = SCGP.GetMapStats(MPQ, GameSpeed, intGameType, intPenalty, MyAcc)

If (SCGP.InitCreate(Handle, MPQ, intGameType, intPenalty, MPQHash, lngStatsCode, lngMyClient, MyAcc, GameName, GamePass, GameStats)=false then
    'handle any error here
end if

Notice I got the game stats string from SCGP.GetMapStats()
The class also has a few handy functions for reading map files.

Public Function GetMapIcon(ByVal strMPQ As String) As Long

This function will accept a path to a map file, and return what type of icon the map has.
For example, 0 = none, 1 = blizzard, 2 = ladder, etc

Public Function GetMapInfo(ByVal strMPQ As String, _
                           ByRef lngWidth As Long, _
                           ByRef lngHeight As Long, _
                           ByRef bIcon As Byte, _
                           ByRef bTitle As Byte, _
                           ByRef bPlayers As Byte, _
                           ByRef bComputers As Byte, _
                           ByRef strTitle As String, _
                           ByRef strDesc As String) As Boolean

This function takes a path to a map file, and returns its width, height, icon, titleset, number of human players, number of computer players, the map name (not file name) and the map description.
Pretty much all the infomation you need, when you click a map on starcraft, and view its info when creating a game.
also, VERY IMPORTANT, is the number of players and computers returned.
You need this number, to derive the correct penalty index (as explained under GetMapStats) for mostly, tvb games.

Public Function GetMapStats(ByVal strMPQ As String, _
                            ByVal bSpeed As Byte, _
                            ByVal intType As Integer, _
                            ByVal bPenalty As Byte, _
                            ByVal strHost As String) As String

This function takes a path to a map file, a game speed, a game type, a penalty for said game type, and your account name, and returns a map stats string.
You need this map stats string when calling the SCGP.InitCreate(), you also need this for sending 0x1C to battle.net, to create the game.
Its very important, you pass the correct penalty value.
for example, it must never be below 1, and never above 7.
In a team game, like team melee, team ffa etc, 1=2teams, 2=3teams, 3=4teams.
For top vs bottom, penalty = the number of players in the away team.
You need the max number of players (Players+Comps, from the GetMapInfo) to get a true list of top vs bottom penaltys.
Top vs bottom penaltys, basicly goes like this:
1 = 7v1
2 = 6v2
3 = 5v3
etc etc etc
but for a map with less than 8 players, it goes somthing like
1 = 5v1
2 = 4v2
3 = 3v3
4 = 4v2
So, its important you pass the correct penalty.
Why is it important?
Because when hosting, joining players will use the game stats string to derive the team infomation, max number of players, etc etc.
Not to mention, I flip the penalty valur around, in the getmapstats function, and the initcreate sub, so that I can just pass it the combo box index.
Makes it simpler on the out side, to list the teams/penaltys the same way starcraft does, and just pass the listindex value to the functions.
(Well, ok, not so important)

Public ReadMPQFile(ByVal strMPQ As String, ByVal strFile As String, ByRef strBuffer As String) As Boolean

This function, takes a path to a MPQ file, the name of a file with in the mpq, and returns the file data in strBuffer.
The function returns false, if it fails.

Now for a list of the current supported events:

Public Event OnJoinLatency()

Speaks for its self -- this is raised after about 8 seconds of joining the game, if the host doesnt respond.

Public Event OnCreate(ByVal strMAP As String)
    strMAP = path to the map file

This is raised 1st, when you create agame, followed by all the other events

Public Event OnEnterRoom()

This is raised when you have enterd the game room.
Normaly, this is the 1st event you get after joining agame, letting you know you're in.
Its also raised if your hosting agame, following the OnCreate() event.

Public Event OnJoinReject(ByVal bReassion As Byte)
    Select Case bReassion
        Case &H0:   "You Have Been Booted.")
        Case &H1:   "You Have Been Banned.")
        Case &H2:   "Game Creater Has Closed All Avalible Slots.")
        Case &H3:   "Game Host Has Left The Game.")
        Case &H4:   "Unable To Join The Game.")
        Case &H5:   "Save Game File Not Found.")
        Case &H6:   "Unable To Write Scenario File.")
        Case &H7:   "Invalid Game Version.")
        Case &H8:   "Invalid Spawn Version.")
        Case &H9:   "Unable To Authenticate Map.")
    End Select

Pretty much speaks for its self there.
Note: this event will be raised, with the reassion 0x04, if the host rejects you'r joing request.

Public Event OnMapStats(ByVal strGameName As String, _
                        ByVal strGamePass As String, _
                        ByVal strGameStats As String, _
                        ByVal intGameType As Integer, _
                        ByVal intPenaltyA As Integer, _
                        ByVal lngPenaltyB As Long, _
                        ByVal lngMaxPlayers As Long, _
                        ByVal intMapWidth As Integer, _
                        ByVal intMapHeight As Integer, _
                        ByVal strSlotSelect As String, _
                        ByVal strRaceSelect As String)

Thses values pretty much speak for them selfs.
The penaltyA value, is the basic penalty index.
The penaltyB, is the value that goes with the penalty index -- like the time in a slaughter game.
strSlotSelect and strRaceSelect are both 12 bytes long. They contain the base stats of each player/game slot. so for example, if the 3rd byte in slotselect is not 0x06, you can not change game room slot 3's state (if you are the host)
if the 4th byte of raceselect is not 0x06, then the 3rd game room slot can not have its race changed.
Kind of like, comps in UMS games, and fixed races in UMS game.

Public Event OnForceName(ByVal strForceA As String, _
ByVal strForceB As String, _
ByVal strForceC As String, _
ByVal strForceD As String)

Raised to tell you the force names, mainly, in UMS games.
For example, the team names in a UMS game.

Public Event OnCheckMap(ByVal lngLengh As Long, _
ByVal lngChecksum As Long, _
ByVal strMapName As String, _
ByRef bGotIt As Boolean, _
ByRef strMapData As String)

Raised when the class wants to know if you need to download the map or not.
The lengh is the lengh of the map file.
the checksum is a checksum of the file -- I just store that in the maps file time.
if you have the map already and dont need to download it, you must set the bGotIt to true, and fill strMapData with the file data, so the class can then send the map to any other players who may need it.

Public Event OnMapDownloaded(ByVal lngLengh As Long, _
     ByVal lngChecksum As Long, _
     ByVal strMapName As String, _
         ByRef strData As String)

Simply telling you, the class has finished downloading the map.
Lengh of the map, checksum of the map, name of the map, map file data.

Public Event OnMapDownloading(ByVal bPercent As Byte, ByVal bSlot As Byte)

tells you that a player in the game room slot, has updated their download percentage.
This is also raised for you're own download progress, as well as any other.

Public Event OnSlotUpdate(ByVal bSlot As Byte, _
  ByVal strAccount As String, _
      ByVal bState As Byte, _
  ByVal enRace As SCGP_RACE, _
  ByVal bTeam As Byte, _
  ByVal lngPing As Long, _
  ByVal bDLPer As Byte)

Raised when a game slot is updated. Explains its self pretty well there.

Public Event OnChat(ByVal strAccount As String, ByVal strChat As String)

Public Event OnSlotPing(ByVal bSlot As Byte, ByVal lngPing As Long)

Raised when a player in the given game room slot, has got a ping update.

Public Event OnPlayerJoin(ByVal strAccount As String, ByVal strStats As String)

Raised when a player joins the game.
This does not include existing players already in the game.

Public Event OnPlayerQuit(ByVal bSlot As Byte)

Raised when a player in a given game room slot, has quit the game.

Public Event OnGameStart()

Explains its self pretty well.
This is also when the road ends.
You should beable to just about idle ingame with 1 or more players, but this class really stops when it comes to game start.
As siad above, its currently only around 20% compleat.

Game room functions:

Public Sub Clear()

Does exacly what it says, clears the class and renders it "offline".

Public Sub Quit()

Tells everyone in the game u have quit.
This does not call the .clear sub, you must do that you're self if you also want to reset the class.

Public Sub Chat(ByVal strChat As String)

Wanna talk to ppl?

Public Sub ChangeRace(ByVal bSlot As Byte, ByVal enRace As SCGP_RACE)

Wanna change you're race, or the race of another player etc?
if your changing your own race, the slot must be 0x08.

Public Sub ChangeTeam(ByVal bTeam As Byte)

Wanna move to another team, or to a new slot in your current team?

Public Sub MovePlayerTeam(ByVal bSlot As Byte, ByVal bTeam As Byte)

Are you the host, and you want to move somone to another team?
You can not move you're self.
This is for TvB game type only.

Public Sub MovePlayerSlot(ByVal bSlot As Byte, ByVal bToSlot As Byte)

Same as moveplayerteam iirc, but you can be abit more selective with what slot you move them to.
Same rules apply as MovePlayerTeam

Public Sub ChangeSlotState(ByVal bSlot As Byte, ByVal bState As Byte)

If your the host, and you want to change the state of a slot, use this.
If you change the state of a slot that contains a player, it will boot them automaticly.
0x05 = computer
0x06 = open
0x08 = closed

Public Sub BootPlayer(ByVal strAccount As String, Optional ByVal bBan As Boolean = False)

Boot or ban a player from the game.

And thats about it, THX GOD, lawl.
what a long ass post ><
I feel like i'm even talking to my self in this post.
Hope you enjoy it, add to it, gib feed backs and take the piss or w/e floats ur boat.
I wouldn't normaly post this sort of infomation, but with starcraft2 just around the corner, and sc/bw pretty dead these days, I figger it's pretty harmless.
This infomation is for educational useage only.

This post will contain the basics infomation on the UDP header that starcraft uses for its game traffic.
The post below this one, will contain a list of command 0 messages.
The post below that one, will contain a list of command 1 messages.
Below that, a list of command 2 messages.

This is how I have formatted the documentation:
(BYTE) -- 8 bit integer
(WORD) -- 16 bit integer
(DWORD) -- 32 bit integer
(STRING) -- Null terminated string
(BYTE[X]) -- Array of bytes, where X is the amount of bytes (1 based)
(VOID) -- Variable lengh block of data

This documentation may not be explained (or spelt) very well, so if you have any questions, spot any errors or have things to add, feel free to post them!


(DWORD) 0x00
(WORD) Checksum
(WORD) Lengh of message (Discluding the 1st dword)
(WORD) Sent Counter
(WORD) Recv Counter
(BYTE) Packet Command
(BYTE) Packet ID (command 0 only)
(BYTE) Player ID
(BYTE) Status

Command 0:
The data appends the header, the headers packet ID value, is the id of the packet.

Command 1:
The packet ID and its data appends the header. The packet ID is at offset 0x10
The packet ID in the header, is always zero.

Command 2:
Like command 1, the packet appends the header.
How ever, command 2 packets are bufferd and sent every X interval.
appending the header is a que of messages (1 or more)
Each has a unique lengh, and a select few are variable.

0x00 = Normal Traffic
0x01 = Verification
0x02 = Resend request
0x04 = Callback

Used to verify count's.

Used to request a given count/packet be resend, due to a brakes in the UDP stream.
For command 2, its possible to have a byte appending the header -- This byte will be an ID of another player in the game. You should respond to such requests with a call back for that player. See callbacks (below)

Call Back:
Used to check up counts between other players.
For example, if player 0 sends a resend request to player 1, but appends player 2's ID behind it, based on the count, player 1 will send player 0 that packet he sent to player 2, including the packet data, but will use the callback status in the responce, as well as filling the player ID value in the header, to that of player 2.
Commonly used in command2 traffic.
For example, if player 0 and 1 has good synq and player 0 and 2 have good synq, but player 1 and 2 are lagging, player 0 will know he has to wait for them to catch up, aka "waiting for player".

The checksum value, is of the whole packet buffer, from the lengh value onwards.
Take the following packet, as an example:

00 00 00 00 28 C4 10 00 00 00 01 00 00 01 FF 00    ....(...........
01 00 00 00                                        ....

The data that is checksum'ed is as followed:

00 00 00 00 28 C4 XX XX XX XX XX XX XX XX XX XX    ....(...........
XX XX XX XX                                        ....

Some easy-to-read VB6 code showing how the checksum is generated:
Note: BufLen is the last byte of the packet buffer, offset 6 would be where the lengh value starts in the header.

    Dim A           As Long
    Dim B           As Long
    Dim C           As Long
    For i = (BufLen) To 6 Step -1
        B = B + Buf(i)
        If (B > &HFF) Then B = B - &HFF
        A = A + B
    Next i
    C = (B * 256) Or (A Mod 255)
    A = &HFF - ((C And &HFF) + (C \ 256)) Mod &HFF
    B = (A + (C \ 256))
    B = &HFF - (B Mod &HFF)
    B = B Or (A * 256)
CheckSum = B And &HFFFF&
Gaming Discussion / Spore! (Finaly)
September 06, 2008, 10:34 AM
Anyone else got spore yet? :)
LOL @ all the bugs, it's almost unplayable :P
Aside from all the bugs, I love it so far :D
I'm at the tribe stage. Where are you at?
General Discussion / Eww YaBB SE Theme Change?
July 09, 2008, 04:04 PM
It's gone all... bright and white! I liked it as the blueish color!
It now hurts my eyes when I look at it, Its like going out side in the daytime. It burn's me!
I can no longseer seser hwat imf typweing, help!