Fwrite stored file and its data from another file archive issue

Hello, I am trying to write a file, and it's file size from an archive file .afs. This file "0611_bgm.adx" is stored inside this .afs file and I need to write the file and all its data complete filesize.

The ADX file header signature is "61 64 78" ASCII "adx" Sizet: 4 Bytes Offset: 4 Bytes

So this is my code below anyone know what I am doing wrong
and if so, correct my code as an example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    FILE* in;
    in = fopen("bgm.afs", "rb");
    fseek(in, 0x1A8C7800, SEEK_CUR);
    unsigned char buffer[1024 * 2];
    fseek(in, 0x1a8C7810, SEEK_END);
    fread(&buffer,sizeof(char),sizeof(buffer), in);
    FILE* out = fopen("0611_bgm.adx", "wb");
    fwrite(&buffer, sizeof(char), sizeof(buffer), in);
    fclose(in);
    return 0;
}


I know the only thing this is doing is writing that one file and writing and storing the rest of the data from the bgm.afs file inside the ADX output file. So getting it to write the adx file and its stored data only would be nice.
Last edited on
this may not be enough.
you seem to know where the file starts: you hardcoded that location. Do you know where it stops? Can you find where it stops (eg, find "adx" again?)?

reading and writing a byte at a time is awful. what you want is to get the address of the start of the file, the address of the end of the file, and just write it that way, in a single call to fwrite instead of a looped mess.
so what you need is to figure out where the file is, start and end locations, and then just dump it.
also, c++ is like living with your family... if you open it, close it, if you borrow it, give it back, etc... close that file when done!

if you need to go over it (eg looking for adx text) try reading a big cut at a time, a gigabyte is a nice round value, and look through that, repeat until done. Remember you could accidentally split on the adx so keep the last 2 bytes when you get a new chunk.
Last edited on
Here are the opcodes for the file stored in memory.

30 36 31 31 5F 62 67 6D 2E 61 64 78 It starts at offset 0x1a8C7809 and ends at offset 0x1A8C7810

I am confused, tho, on how you mean?
Code Example would make it easier to understand your point of view?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    FILE* in;
    in = fopen("bgm.afs", "rb");
    fseek(in, 0x1A8C7800, SEEK_CUR);
    unsigned char buffer[1024 * 2];
    fseek(in, 0x1a8C7810, SEEK_END);
    fread(&buffer,sizeof(char),sizeof(buffer), in);
    FILE* out = fopen("0611_bgm.adx", "wb");
    fwrite(&buffer, sizeof(char), sizeof(buffer), in);
    fclose(in);
    return 0;
}


This is what I tried.
Last edited on
I believe the code I pasted above in my last apply might work.
If I have the correct addresses in memory where the file is stored
and the address where it ends.
If not, please let me know what I am still doing wrong.
A bit of advice:
PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either
0x1a8C7809 and ends at offset
0x1A8C7810

This is awfully small... a few bytes not even 10?

the code is better,
generally..
size = endoffset - startoffset
buffer needs to be size or larger
fread size bytes (sizeof char is 1) not buffer size (you only want the amount in the file)
but generally you are close, I think your issue is just the size / start end offset problem.

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    FILE* in;
    in = fopen("bgm.afs", "rb");
    fseek(in, 0x1A8C7800, SEEK_CUR);
    unsigned int buffer = 890826768;
    fseek(in, 0x1A8C7810, SEEK_END);
    fread(&buffer, 1,1, in);
    FILE* out = fopen("0611_bgm.adx", "wb");
    fwrite(&buffer,1, 1, out);
    fclose(in);
    return 0;
}


I believe all is left is, making sure the start and end offsets are correct.
It outputs the file with only 1byte
So the file size is still wrong or the start and end addresses are wrong?
I am curious if I only have the Start and End Static Addresses and not the Start and End Dynamic Addresses?
Furthermore, I am using HXD Hex Editor to get the position in memory where the start and end offset addresses are located.
Is the code any better?
Last edited on
the code is worse. you put a giant number into a char (max, 255).
you are back to reading 1 byte at a time.
this code certainly writes one byte, line 14.
it looks like you want to do something practical, maybe for work, but to do that you need to do something simple first, to get a good handle on what you need to do.
try writing a simple array of say 0 to 100, as bytes, to a binary file and reading it back in.
I suspect you don't have the right offsets or some critical piece of file format information, but you also seem to lack understanding of the tools.
is this C intentionally, or meant to be C++?

is this an audio file?

is this what you need??
http://wiki.xentax.com/index.php/GRAF:AFS_AFS#Format_Specifications
Last edited on
I have all the information needed:
I believe it is just the offsets are wrong
and there is not enough memory allocated to the buffer.
Perhaps something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

#define STARTOFF	0x1a8C7809
#define ENDOFF		0x1A8C7810

int main()
{
	const unsigned bufSze = ENDOFF - STARTOFF;
	unsigned char buffer[bufSze];
	FILE* in = fopen("bgm.afs", "rb");
	FILE* out = fopen("0611_bgm.adx", "wb");

	if (in == NULL || out == NULL) {
		puts("Cannot open files");
		return 1;
	}

	fseek(in, STARTOFF, SEEK_SET);
	fread(&buffer, sizeof(buffer), 1, in);
	fwrite(&buffer, sizeof(buffer), 1, out);
	return 0;
}

Last edited on
Ok. If that format I linked is the thing you are doing, it has the offsets, just read them.
After spending most of my night thinking this over and compiling your code as well, given.It spits an output with 1 byte stored inside the output. I looked and brushed up on my knowledge on this subject. And came to find out my code rewritten which I will give below is correct but, I am using the static addresses and if we all know they always move around in memory, so I need to relocate these addresses but look for the dynamic addresses instead and see if I can determine if there is a stored file inside the bgm.afs with a memory amount stored at that dynamic address in memory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>                     // Need this for fopen fwrite etc

// We use this simple function to write data to our file
void fileout(char* str)

{

    FILE* fp;
    fp = fopen("0611_bgm.adx", "a+");
    fprintf(fp, "%s", str);         //       append to the end of the file
    fclose(fp);

}// End fileout(..)

long FileSize(char* szFileName)

{

    FILE* file = fopen(szFileName, "rb"); // Open the file
    fseek(file, 0x001BC800, SEEK_CUR);
    long file_size = ftell(file);         // Get the current position
    fseek(file, 0x001BC820, SEEK_END);             // Seek to the end
    long file_size1 = ftell(file);         // Get the current position
    fclose(file);
    return file_size , file_size1;                     // We have the file size, so return it

}// End FileSize(..)



//Program Entry Point

void main(int argc, char* argv[])

{

    char szFileName[] = "bgm.afs";    // Our input afs
    char buf[500];                        // Large temp char buffer
    long iFileSize = FileSize(szFileName);
    fileout(buf);

}// End main(..) 


So that being said, If I find the dynamic addresses and managed to dump the file, I will post up my code if it helps others do the same.
Last edited on
...files do not have dynamic memory.
a file ... you can think of it as sequential bytes on the disk. It isnt always, but you don't care right now, the OS and disk hardware fix that for you before you ever get near it (see disk defragmentation and such). What you see as a 'file' from the disk is really a piece of memory loaded with the file data, already sequential.

so if you read the whole file into one char array:
char filedata[10000000000ull];
fread(..etc)
then filedata[1000] will be the same every time you run the program.
&filedata will not be, but you should not care, work with it from the array's offsets.


Thanks for the clarification. I always heard of people talking about static memory addresses always shift and move around, so the static address in cheat engine will never be valid once you exit the program and re debug it. Then you need to find the static address again. So this makes a patch to a sequence of bytes with a higher value, let's say, for health hard to do because static addresses seem to shift and change in memory. So I was hearing I would need to find a dynamic address instead of this, seems to never shift or change in memory once debugged in cheat engine. I figured this same type of criteria applied here as well.
that is true for what is in memory of a running program.
files, from a disk, will be handed to you on a platter in sequential form with an offset you can just use (usually, you provide this, its your buffer in fread. buffer will move around, but you don't care: its still named buffer and you can still get to where you need to be each time it runs).

your risk: if you hard code where the offsets are in the archive, if someone changes the archive, you will be wrong...
Last edited on
Interesting, I figured that much hearing those statements that what was stated was true.
Now, interesting to say, I never knew when a file is stored inside another file you handle it in sequential form with an offset, which is very interesting. Now, can you take the opcodes at that offset position you know stores a file and, get the size of that file stored in that sequential bytes based on the bytes and offset location? So for example, if I take those bytes and try to get the size of those sequential of bytes, will that give me the size of that file stored at that memory location? So I can store the size I got in my buffer?
Last edited on
opcodes means: in an executable file (.exe, .dll, .scr, things like that) there are commands to the CPU to do things.
data files do not contain opcodes.

every file has a defined format that is specified somewhere. Some of them are not public knowledge.

you need to read the file format, and do what it says to get the data you can from it. Some files have begin/end codes, and you iterate looking for them. If the format I gave you is right, follow it. If not, find the right one...
Topic archived. No new replies allowed.