Valhalla Legends Forums Archive | General Programming | bncache.dat splitter

AuthorMessageTime
BreW
So i decided to make a quick splitter for bncache.dat, but it seems to mix up a few things here and there (for example, half of the ToS is in icons.bni). Can anyone see what i might be doing wrong?

EDIT** I looked at it in a hex editor closer and it appears as if i'm doing nothing wrong at all-- but apparently the function that gets the file has something to protect against this. am i overlooking something in the headers?

[code]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

char *memmem(char* haystack, size_t hl, const char* needle, size_t nl);

int main() {
const char *blah = "\x44\x01\0\0\0\0\0\0\0\0\0\0";
const char *filename = "C:\\Program Files\\Starcraft\\bncache.dat";
char *found;
char strbuf[0x80];
char strbuf2[0x80];
char *buffer = (char *)malloc(1000000);
char *tmpbuffer = buffer;
FILE *file = fopen(filename, "rb");
if (!file) {
printf("Invalid file.\n");
return 0;
}
ZeroMemory(buffer, 1000000);
fread(buffer, 1, 975439, file);
fclose(file);
int i = 0;
while (tmpbuffer <= (char *)(buffer + 1000000)) {
found = memmem(tmpbuffer, buffer + 1000000 - tmpbuffer, blah, 12);
if (found) {
strncpy(strbuf, found + 0x40, 0x80);
tmpbuffer = found + 12;
printf("0x%08x  %s\n", tmpbuffer - buffer - 12, strbuf);
sprintf(strbuf2, "C:\\Documents and Settings\\Owner\\Desktop\\Cache\\%s", strbuf);
file = fopen(strbuf2, "wb");
if (file) {
fwrite(tmpbuffer + 312, 1, memmem(tmpbuffer,
buffer + 1000000 - tmpbuffer, blah, 12) - tmpbuffer - 312, file);
fclose(file);
} else {
printf("fopen() failed\n");
}
i++;
} else {
break;
}
}
free(buffer);
return 0;
}

char *memmem(char *haystack, size_t hl, const char *needle, size_t nl) {
if (nl > hl)
return NULL;
for (int i = hl - nl + 1; i; --i) {
if (!memcmp(haystack, needle, nl))
return haystack;
++haystack;
}
return NULL;
}
[/code]
February 17, 2008, 3:41 AM
Ringo
[quote author=brew link=topic=17328.msg176446#msg176446 date=1203219664]
So i decided to make a quick splitter for bncache.dat, but it seems to mix up a few things here and there (for example, half of the ToS is in icons.bni). [/quote]
IIRC, it doesnt resort the file when it replaces files, it just writes over them in what ever space it can find (or appends to the file)
I just spend the last 20 - 30 mins looking at a few hex dumps of the file, but im not sure where the file lengh is saved, nore the file next position.
I got board of it, so i just targeted the header of each file (think thats what your doing to)
Heres my test code for you to compare with:
[code]
Private Type CACHEHEADER
    HeaderSize As Long
    D2         As Long '0x00
    D3         As Long '0x00
    Unknown1   As Integer
    Unknown2   As Integer
    Unknown3   As Integer
    Unknown4   As Integer
    D4         As Long
    FT1        As String * 8
    FT2        As String * 8 'last modifyed
    FT3        As String * 8
    FT4        As String * 8
    FT5        As String * 8
    FileName   As String * 260
End Type

Private Sub ParseBNCache(ByVal strData As String)
    Dim strBNGHeader As String * 32
    Dim lngFilelengh As Long
    Dim lngFileCount As Long
    Dim i            As Long
    Dim i2           As Long
    Dim lngPos       As Long
    Dim H            As CACHEHEADER
    strBNGHeader = Left(strData, 32)
    lngFilelengh = GetDWORD(Mid(strBNGHeader, 9, 4))
    lngFileCount = GetDWORD(Right(strBNGHeader, 4))
    lngPos = 33
    Debug.Print "Opening bncache.dat File With " & lngFileCount & " Files"
    Debug.Print "File Is " & lngFilelengh & " bytes"
    If Not GetWORD(Mid(strData, lngPos, 2)) = &H144 Then
        Debug.Print "Skipping 32780 Bytes Of Shit"
        lngPos = lngPos + 32780
    End If
    For i = 1 To lngFileCount
        lngPos = InStr(lngPos, strData, MakeDWORD(&H144) & MakeDWORD(0) & MakeDWORD(0))
        CopyMemory H, ByVal Mid$(strData, lngPos, &H144), &H144
        lngPos = lngPos + &H144
        i2 = InStr(lngPos, strData, MakeDWORD(&H144) & MakeDWORD(0) & MakeDWORD(0))
        If i = lngFileCount Then i2 = lngFilelengh + 1
        Debug.Print GetSTRING(H.FileName) & " Is " & (i2 - lngPos) & " bytes"
        Call DumpToFile(App.Path & "\" & GetSTRING(H.FileName), Mid(strData, lngPos, (i2 - lngPos)))
    Next i
End Sub
[/code]
Yeah, really messy I know! :P
Heres the out put for my SC cache:
[code]
Opening bncache.dat File With 17 Files
File Is 235474 bytes
Skipping 32780 Bytes Of Shit
lockdown-IX86-01.mpq Is 6347 bytes
lockdown-IX86-08.mpq Is 6415 bytes
icons_STAR.bni Is 6081 bytes
bnserver.ini Is 364 bytes
icons.bni Is 16379 bytes
tos_USA.txt Is 18356 bytes
lockdown-IX86-18.mpq Is 6424 bytes
9bf3c9a16c7973f3dd813f35a547ba6d.mod Is 15872 bytes
ad000c79.smk Is 13424 bytes
lockdown-IX86-03.mpq Is 6328 bytes
ad0017c6.smk Is 16372 bytes
ad001792.smk Is 29548 bytes
lockdown-IX86-05.mpq Is 6423 bytes
lockdown-IX86-12.mpq Is 6425 bytes
lockdown-IX86-15.mpq Is 6342 bytes
lockdown-IX86-19.mpq Is 6350 bytes
ad001798.smk Is 29704 bytes
[/code]

And one of my d2's:
[code]
Opening bncache.dat File With 113 Files
File Is 1756548 bytes
Skipping 32780 Bytes Of Shit
ver-IX86-4.mpq Is 6888 bytes
bnserver-D2DV.ini Is 364 bytes
BNNews-D2DV Is 256 bytes
BNNews-D2DV Is 758 bytes
BNNews-D2DV Is 1268 bytes
BNNews-D2DV Is 1522 bytes
BNNews-D2DV Is 1846 bytes
BNNews-D2DV Is 2157 bytes
BNNews-D2DV Is 2474 bytes
BNNews-D2DV Is 2699 bytes
BNNews-D2DV Is 3043 bytes
ad000c7b.smk Is 14924 bytes
d0070241c8b1f4cf65e4b06e39b064b0.mod Is 17661 bytes
ad000c77.smk Is 16400 bytes
ad000c85.smk Is 14812 bytes
5a134a365dce5c032ec479f759e2b3bc.mod Is 16787 bytes
ver-IX86-2.mpq Is 6898 bytes
ad000b0d.pcx Is 13971 bytes
dfe85d2259c222bfb45b6fdbbf47c5b7.mod Is 17240 bytes
1add92756d91ccfba202ea2c366a796c.mod Is 16951 bytes
ver-IX86-1.mpq Is 6906 bytes
ad000c83.smk Is 17156 bytes
8d1fbbb6489bcb485a98956b1c7a1429.mod Is 17089 bytes
ad000c75.smk Is 23868 bytes
ad000c81.smk Is 18672 bytes
ad000c79.smk Is 13424 bytes
eeff85562a8b753e05efa461c92a7d44.mod Is 16756 bytes
86bea030a0f4d339fee7abad93abe3a1.mod Is 17122 bytes
d7ae409d804a44bacb6523ddb3268a44.mod Is 17245 bytes
ver-IX86-7.mpq Is 6891 bytes
c696ad43a20db64ec1cdc91a58042b59.mod Is 17188 bytes
ad000c87.smk Is 16472 bytes
fe9de79a2f032e042575d2eef891b682.mod Is 17390 bytes
429e8e1bade87efccf54f814dfc0c107.mod Is 17325 bytes
ad000c57.smk Is 16844 bytes
6c4202c2137a4b3c6202a07bcd7a1c88.mod Is 17292 bytes
ad000c89.smk Is 14044 bytes
ver-IX86-3.mpq Is 6888 bytes
a9a659e6488fc962179610c35f78ebbf.mod Is 16437 bytes
49e3e39825859fdbf6529667fe7fd6ec.mod Is 16264 bytes
46d6adf9143678d3ec15a36c8da5f195.mod Is 17973 bytes
ad000c55.smk Is 15624 bytes
c3f55cb9043c64cb05debafabf1500ad.mod Is 17210 bytes
ver-IX86-6.mpq Is 6894 bytes
4a3a508027cb8e9356c23d43186e2840.mod Is 17349 bytes
5d676b94723623face51f04964688229.mod Is 17345 bytes
52fc408a46230e3e7c97ef8bf204b5cb.mod Is 17856 bytes
e5b930a2a69f789a9ee3b8e2d7bc0ed6.mod Is 17701 bytes
4a17d1408abec665cb885396d3941f6d.mod Is 17085 bytes
0a9855ba2503ff612e58475c71e9a006.mod Is 17400 bytes
fbaace734dece6ecef2ec11d0ec8a072.mod Is 17748 bytes
be5d0d3c1f5cc41ce0e9b14987845c57.mod Is 17231 bytes
b0e9ab1178940b23cf1c72862f3ce888.mod Is 17714 bytes
ver-IX86-0.mpq Is 6894 bytes
45d2b0283a051d69a3e8446d6f807cc1.mod Is 17472 bytes
9e9b7c9874061d2bd4368d8a414ad5dc.mod Is 16520 bytes
ver-IX86-5.mpq Is 6894 bytes
017d3ac4ff30ad7e29d502e6cd53d4d8.mod Is 17278 bytes
8c9f3289321e6e69767732842604d816.mod Is 17226 bytes
06aa575d6a7095c962076f77525f5a95.mod Is 16386 bytes
0182bcdcc88ae320fa540a4736c3d70b.mod Is 16993 bytes
5960572f93756ef686d47f340903d1f3.mod Is 17905 bytes
b37b08735a5cd732907d82b62251cb8f.mod Is 17291 bytes
a7f180ca61c9a3e1f2ddcfbd6d2e088e.mod Is 16625 bytes
e7e230ba0b8031abf089c1868675428f.mod Is 17684 bytes
9cf7b2f4fa8cbd571a846f59157e81c7.mod Is 17272 bytes
182f81d9bbe67c6d7a18e16721d73831.mod Is 16568 bytes
8a39abce7b7f0759020955041cf5b0a0.mod Is 17501 bytes
5b9063249231356cecafd5ce40a927a1.mod Is 17526 bytes
780240bf8b9c5734dce4d16cfb208100.mod Is 16714 bytes
413e4b5ee08b8a0e888a668cb6b1d901.mod Is 16720 bytes
9b4146f3b3a34e5a5b8db46e4e08dae3.mod Is 17087 bytes
ed4e73c66655d3187aaef13b42e5a0fd.mod Is 17338 bytes
fe973eb86236374e66100d3fe9ede172.mod Is 16553 bytes
b763cdcb99751036576954d63955bcb6.mod Is 17331 bytes
577b688fdf9701b4264d5ee98531b574.mod Is 17193 bytes
904bbf42207b25639dcd3a3aef322193.mod Is 17125 bytes
de9ba41949afa003188192bab035abef.mod Is 17242 bytes
372304489feecdf323a48d3812121ab7.mod Is 17279 bytes
d8b09945467fc218064090d0eea3487a.mod Is 17277 bytes
409a51fc9e098f8cb5cce31d7b5bec73.mod Is 16022 bytes
d1b0b34b33f414278c7dcd310cd8bc9d.mod Is 16227 bytes
249fc2bc48353d9511301e5c039fffaf.mod Is 17522 bytes
2bb07b27922d96647e4efb616b1cca8b.mod Is 17413 bytes
4398573af55d423d0556451a2314b0b0.mod Is 17149 bytes
ceba19ffc3f55beffea1444c188eb007.mod Is 16389 bytes
926a116c663e406ded4c2c59565d7ff1.mod Is 17244 bytes
87b062ee74543af773d4535fc0ef05f8.mod Is 16940 bytes
46a18ff0b15cc99cade15c6d0f8415ed.mod Is 17061 bytes
a270c48221c24caee184f0ba6990afd3.mod Is 16431 bytes
b3cd0ae475812cfae64a5b9d2b0a1c0b.mod Is 16329 bytes
057003b266b217b91bf73332aeb67b01.mod Is 16181 bytes
91efe3da4f33ff0c9ee81b06657e7935.mod Is 16668 bytes
b830a7b36be8a5717d17e873f3cbc4b1.mod Is 16951 bytes
7892946dfa21b6f153d8c9c0689eb5f6.mod Is 16319 bytes
53e6c03240dca30f2ef8b7660b1d7c40.mod Is 18259 bytes
c058085c5679495feaab314c65969fa2.mod Is 16985 bytes
d354a34821e5077d87488d01ba848657.mod Is 16681 bytes
0681e233571e6a28bdc0625803626015.mod Is 16167 bytes
5787a06dec86416d3fba994bc27239d0.mod Is 16841 bytes
9b32e6984ff7aab6421cdab4595d072d.mod Is 17478 bytes
913295ebe495a6d45532f103c55dcb7f.mod Is 17881 bytes
7bba436091bfd983a294a6e29e19d269.mod Is 16884 bytes
b37e39fd0c50c8de57a911f1f80e7a2d.mod Is 17796 bytes
2feac224e2302951fc6b6888119bd609.mod Is 17256 bytes
043107de20c12e19b9c4b4278da13b36.mod Is 17694 bytes
1ba5abc8630fbca6d035ede9344e7c6c.mod Is 17659 bytes
c36b2622550a67cfacca44724d0d1625.mod Is 16162 bytes
d042966bacc11de370217c57184b9549.mod Is 17330 bytes
261adb141554e187a6438727494ce3a1.mod Is 17565 bytes
224430a8e8fd81440b4bbbb897a9f77a.mod Is 16706 bytes
4d7621156f131b56c1083736e3974c58.mod Is 16845 bytes
a069689c5d246a1dee7b95475eb806e2.mod Is 16873 bytes
[/code]
All mine came out just fine.
Aside, might be worth deleteing the cache and let it refill, then try parseing it (if nothings wrong with your code)

Hope this helps
February 17, 2008, 10:41 AM
BreW
Nice work ringo :P
Still dunno how to get the lengths
Blizzard has it all worked out somehow, tho, check out QueryBNCache (battle!190278B0h) if you're interested. It's a huge function, and it just reads/writes stuff to the cache so i'm not sure if reversing it is worth the time, but it is somewhat interesting (it does a buncha xor and bit shift math and checks if two seperate values come out to be the same, *most likely* an integrity checking scheme). I can't seem to figure out what the last parameter is, though. (it takes something in, then modifies it byref to be the NumberOfBytesWritten value from WriteFile)
February 17, 2008, 3:31 PM
St0rm.iD
part of me says you want to use memcpy and not strncpy
February 17, 2008, 9:26 PM
BreW
[quote author=Banana fanna fo fanna link=topic=17328.msg176476#msg176476 date=1203283610]
part of me says you want to use memcpy and not strncpy
[/quote]
while wasting valuable cpu cycles to copy over null bytes, right?
February 17, 2008, 9:34 PM
Kp
[quote author=brew link=topic=17328.msg176480#msg176480 date=1203284058]
[quote author=Banana fanna fo fanna link=topic=17328.msg176476#msg176476 date=1203283610]
part of me says you want to use memcpy and not strncpy
[/quote]
while wasting valuable cpu cycles to copy over null bytes, right?
[/quote]

I hope you're joking.  You do realize strncpy will stop after it hits a null byte, whereas memcpy will keep going, right?
February 18, 2008, 12:52 AM
BreW
I am not joking. I do intend to copy ONLY until the null byte. Anything after that is irrellevant for what I am using the buffer for. I would have normally used just strcpy, but since i'm feeling a bit cautious today i figured i'd use strncpy to be safe in case there is some abnormally long filename in bncache.
February 18, 2008, 12:57 AM
xpeh
Can you post file format instead of parsing code?
January 31, 2009, 4:34 AM

Search