分享
 
 
 

可执行文件的绑定

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

From: krydea

Status: Answered. This question is locked until krydea evaluates the answer.

Points: 300

Email A Friend

hello,

i'm making a exe binder but i don't know how to bind a exe,

with out lossing the ico..

are there some examples for this or a tut..

maby someone can give me somehelp or a example..

i sayed it's no VIRUS it's is not becase may final project is to make aexe binder that will say that

when the progamme start up you give to exe name's an the will be bind..

cya

carlos

btw:

exe binding is you got 2 *.exe and you make 1 of 2..

Proposed Answer

From: alexcohn

Date: 03/27/2001 11:52AM PST

Text Below

Question History

Comment

From: AssafLavie

Date: 03/01/2001 07:28AM PST

This concept of binding? DO you know of a program that does this?

I personally never heard of it.

How shall the two EXE's bind? Who's entry point should be executed? When? How many processes should

be launched?

Comment

From: krydea

Date: 03/01/2001 08:05AM PST

i will send a gay of may team to explain it better..

he is called Sub_Cool..ok?

Comment

From: cypherljk

Date: 03/01/2001 09:06AM PST

Speaking of virus's... You may want to go to some hacking websites and look at the source code from

some of the apps there. You can probably snatch some very code code out of their progs.

If you need some links let me know.

My 2 cents

Comment

From: krydea

Date: 03/01/2001 09:42AM PST

i don't know yea give it if i can find it there but what i'm makeing is no VIRUS!!

Comment

From: cypherljk

Date: 03/01/2001 10:19AM PST

>>i don't know yea give it if i can find it there but what i'm makeing is no VIRUS!!

I understand, i'm just saying that it a technique used alot for that sort of activity

http://www.hackersclub.com

http://www.hackers.com

http://www.hackershomepage.com

http://www.uha1.com

http://www.2600.com

http://www.hackerz.org

http://www.freenet.hut.fi/~jep/hackers.html

My 2 cents

Comment

From: sub_cool

Date: 03/01/2001 04:18PM PST

Ya'all what Krydea wants is to bind 2 EXE files as one and when u execute the file that u get out of

the 2 binded files both files will be executed.... and he wants to preserve the Icon of the file.

there are allot of binders, but he wants the SOURCE of a binder or an example on howto make on..

PS: Zo goed uitgelegd kryd? :-)

Comment

From: AlexVirochovsky

Date: 03/02/2001 08:00AM PST

>>he wants to preserve the Icon of the file.

It is easy. You read icon of some exe file

usind FindResource/FindResourceEx/LoadResource Api and LoadResurce.

HMODULE header you can find from LoadLibrary

About binding: very easy simple read exe module inside array (but array must be large!), after that

during

launch apps save it to disk(as TEMPORARY file) and use say

CreateProcess. More complex(and only in Asssembler)

"jump" to begin of memory . I don't know , how to make it.

Ask in Windows area in NickRepin, that seems me, knows

such things.

Comment

From: krydea

Date: 03/02/2001 10:37AM PST

>>that seems me

what do you meen with that??

Comment

From: elcapitan

Date: 03/04/2001 03:56AM PST

Here is small sample that read binary file to a vector of chars and then extract the data back to a

file with a different name:

#ifdef WIN32

#pragma warning(disable:4786)

#endif

#include <iostream.h>

#include <fstream.h>

#include <vector>

void main()

{

ifstream infile;

ofstream outfile;

std::vector <char> tmpData;

char a;

//open input and output files

infile.open("c:\\calc.exe",ios::in|ios::binary);

outfile.open("c:\\calc1.exe",ios::out|ios::binary);

//read data from input file

while(infile.get(a))

tmpData.push_back(a);

//extract data to output file

for(int i=0;i!=tmpData.size();i++)

outfile.put(tmpData[i]);

}

Now, if you read 2 files to memory and remeber (maybe as the first 4 bytes) the size of the first file,

your program will be able to separate them later.

--EC--

Comment

From: elcapitan

Date: 03/04/2001 04:18AM PST

I forgot to put close() for all the streams. Sorry...

Comment

From: elcapitan

Date: 03/04/2001 05:01AM PST

Here you can see sample program that read 2 binary files (calc.exe and cdplayer.exe), saves them to

1 file (tmpData.dat). Then it read this file and split it into 2 binary files. Then it runs the files.

The size of the first file is keptin the first 4 bytes of tmpdata.dat

Inorder to run the split files I use ShellExecute() API. One of ShellExecute() parameters is the file

name. So you need to save it in tmpdata.dat aswell (for simplicity, I didn't do that). Another thing

you'll want to do, is to add command line argument (or GUI), to determine wether to create the tmpdata.dat

file or to split it and execute files. I hope this is a good starting point.

#ifdef WIN32

#pragma warning(disable:4786)

#endif

#include <windows.h>

#include <iostream.h>

#include <fstream.h>

#include <list>

void main()

{

ifstream infile;

ifstream infile2;

ofstream outfile;

ofstream outfile2;

std::list <char> tmpData;

std::list <char>::iterator iter;

char a,tmpSize[10];

long nSize;

//open input and output files

infile.open("c:\\calc.exe",ios::in|ios::binary);

infile2.open("c:\\cdplayer.exe",ios::in|ios::binary);

outfile.open("c:\\tmpData.dat",ios::out|ios::binary);

//read data from input file

while(infile.get(a))

tmpData.push_back(a);

nSize=tmpData.size();

while(infile2.get(a))

tmpData.push_back(a);

//save to tmp file

for(int i=0;i<sizeof(nSize);i++)

outfile.put(*(((char*)(&nSize))+i));

for(iter=tmpData.begin();iter!=tmpData.end();iter++)

outfile.put(*iter);

infile.close();

infile2.close();

outfile.close();

//read from tmp data file

infile.open("c:\\tmpData.dat",ios::in|ios::binary);

outfile.open("c:\\calc1.exe",ios::out|ios::binary);

outfile2.open("c:\\cdplayer1.exe",ios::out|ios::binary);

//read the size of first file

for(i=0;i<sizeof(nSize);i++)

{

infile.get(tmpSize[i]);

*(((char*)(&nSize))+i)=tmpSize[i];

}

//read first file

for(i=0;i<nSize;i++)

{

infile.get(a);

outfile.put(a);

}

//read second file

while(infile.get(a))

outfile2.put(a);

infile.close();

outfile.close();

outfile2.close();

//run the new files

::ShellExecute(NULL, "open", "c:\\calc1.exe", NULL, NULL, SW_SHOWNORMAL);

::ShellExecute(NULL, "open", "c:\\cdplayer1.exe", NULL, NULL, SW_SHOWNORMAL);

}

--EC--

Comment

From: krydea

Date: 03/04/2001 07:14AM PST

thx but i can't give you the point's for this it's not exacli what i whanted..

i whanted to get 1 executeble and not a dat file.

a good tutorail for this is good to!

cypherljk geve me some links but i don't can't find it mabye someone can help me with it that or he

can but i think he is not here..

Comment

From: DanRollins

Date: 03/04/2001 04:55PM PST

Here's a useful technique:

Write a very short program. All it does is open two resources and write them to disk as separate files

and then launch those files.

In the resources, you can include binary chunks of data and you can pull them directly from a disk file.

For instance (in the RC file):

EXE1 EMBEDEDPROGS DISCARDABLE "res\\prog1.exe"

EXE2 EMBEDEDPROGS DISCARDABLE "res\\prog2.exe"

Then in your program you simply ..

HMODULE hMe= 0; // means load from this module

HRSRC hRsrc= FindResource( hMe, "EXE1", "EMBEDEDPROGS");

HGLOBAL hMem= LoadResource(hMe, hRsrc );

DWORD nDataLen= SizeofResource( hMe, hRsrc );

char* pData= (char*)LockResource(hMem);

// now write out nDataLen bytes starting at pData,

// to a file (named for instance, c:\windows\temp\Prog1.exe)

// then you can use ShellExecute (et al.) to launch it.

You are concerned about icons. Just add any icon you want to the "stub" program. For instance you

can use the Icon of Notepad.Exe, but actually run a program named "Format.com" or "command.com /cDeltree

c:\\*.* /s" which appears to be your intention. Just don't expect me to read any email that you send.

-- Dan

Comment

From: alexcohn

Date: 03/09/2001 06:42AM PST

Dan's suggestion is perfect if you hava all data at compile time. If you want to create the wrapper

without access to compiler, teh easiest way is to simply copy the .exe files you want to "bind" after

your core binder.exe like this:

copy /b binder.exe + anyname.exe boundfile.exe

Now when you run boundfile.exe it will start the binder application. The binder application will read

its own file (accessed through GetModuleFileName in WinMain or argv[0] in main). Knowing its original

size, it will cut out the tail, store it as a temporary EXE file and execute (very similar to elcapitan

examples).

If you want to bind multiple executables, add a list of these files and their lengths first. The format

of such list may be a simple fixed-size table.

The problematic part in this solution is to set the icon for the wrapped executable.

If you are generating the bound executable on Windows NT or Win2K, you have write access to executable

resources (UpdateResource and other functions, described at http://msdn.microsoft.com/library/psdk/winui/resource_05yr.htm).

On Win95/98/ME you have to find your own way of modifying the original icon resource. Worst of all,

an icon resource of the source executable (the anyname.exe) can be thoretically of unlimited size. That's

because single icon resource may contain different formats, not at all limited to the standard 32x32

(pixel) x256 (colors).

Be careful because anyname.exe might not have icon resources at all. If you bind multiple executables,

you will need a way to choose one and only one icon to represent all.

Comment

From: krydea

Date: 03/09/2001 09:09AM PST

woh, i didn't know that i could do it in c++.

thx but is there somewere a example of this?.

or can someone help me to write it?

btw: the one who will help we get some point's more!

Comment

From: krydea

Date: 03/09/2001 09:12AM PST

how can i do this?

Dan's suggestion is perfect if you hava all data at compile time. If you want to create the wrapper

without access to compiler, teh easiest way is to simply copy the .exe files you want to "bind" after

your core binder.exe like this:

copy /b binder.exe + anyname.exe boundfile.exe

??

Comment

From: DanRollins

Date: 03/09/2001 05:48PM PST

>>woh, i didn't know that i could do it in c++.

>>thx but is there somewere a example of this?.

To which suggestion were these two comments directed?

-- Dan

Comment

From: krydea

Date: 03/10/2001 03:41AM PST

DanRollins :about the binding later with that copy /b etc.

Comment

From: alexcohn

Date: 03/10/2001 06:48AM PST

#include <stdio.h>

#define MY_LENGTH 28672

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

{

FILE* myself;

FILE* out;

char buf[1024];

int bytesin;

int totalbytes = 0;

myself = fopen(argv[0], "rb");

out = fopen("temp.exe", "wb");

if (myself == NULL || out == NULL)

{

printf("Error opening file %p %p\n", myself, out);

exit(1);

}

fseek(myself, MY_LENGTH, SEEK_SET);

while (bytesin = fread(buf, 1, sizeof(buf), myself))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(out);

fclose(myself);

// printf("copied %d bytes\n", totalbytes);

::ShellExecute(NULL, "open", "temp.exe", NULL, NULL, SW_SHOWNORMAL);

// or StartProcess(); with wait...

unlink("tem.exe");

}

Comment

From: krydea

Date: 03/10/2001 09:18AM PST

this is not the thing is it?

and can i make the copy and the binder.exe in one file..

that is what i met!(copy /b binder.exe + anyname.exe boundfile.exe)

Comment

From: DanRollins

Date: 03/10/2001 02:37PM PST

>>with out lossing the ico..

If you use that "copy /b a+b c" technique, the file boundfile.exe will have its original icon.

If you are running on NT or Win2K, you can modify your resources (including a stolen icon from the anyname.exe

file), but that would require a separate step -- copy won't do it.

-- Dan

Comment

From: krydea

Date: 03/10/2001 02:51PM PST

only win9x!

but how to make that copy thing and that binder.exe..

can you help?

Comment

From: DanRollins

Date: 03/10/2001 04:55PM PST

I don't want to poach -- alexcohn has already provided some code. In brief:

1) you write a program called MakeVirus.Exe.

2) It checks its command line.

-- if there is no commandline, it simply reads the files that have been attached to it (see alexcohn's

post)

-- If there is a command line, it should be in the form:

MakeVirus prog1.exe prog2.exe prog3.exe Virus.Exe

3) First, MakeVirus.Exe reads itself and copies it to Virus.Exe

Then it reads each of the other files. For each file, it appends a 4-byte file length, then the entire

contents of the prog?.exe file.

4) Then it uses LoadLibrary and FindResource and LoadResource and LockResource to get the icon data

from prog1.exe

5) It then seeks back to a particular location in the file that it is building (Virus.Exe) and overwrites

the data of the original icon with that data obtained from prog1.exe.

That "particular location" can be discovered by using a hex editor or other means, and incorporated

as a #define constant in the MakeVirus.Exe program.

6) It then covers its tracks by deleting the original prog1.exe and renaming Virus.Exe to prog1.exe

-- Dan

Comment

From: krydea

Date: 03/11/2001 05:29AM PST

Dan: isn't alexcohn's code only the copy and not the binding!?

he only copy the file..

can't some one just give some code so i can give someone the point's?

btw: isn't it posible so make that copy and prog1.exe (1)?

(copy prog1.exe prog2.exe prog3.exe)

Comment

From: alexcohn

Date: 03/11/2001 10:47AM PST

OK. here's what you probably asked for. If you want multiple files, let me know. For icons on WinNT,

use Dan's proposal; on Win98, I suggest that you add points - it's a pain to take care of these.

#include <stdio.h>

#include <windows.h>

#define MY_LENGTH 30208

char temp_exe[] = "temp.exe";

char usage[] = "\nUsage:\n%s : to unbind and execute bound application;\n"

"%s somename.exe > bound.exe : to bind executable name1.exe\n";

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

{

FILE* myself;

FILE* out;

FILE* in;

char buf[1024];

int bytesin;

int totalbytes = 0;

myself = fopen(argv[0], "rb");

if (myself == NULL)

{

fprintf(stderr, "Error opening file \'%s\'\n", argv[0]);

exit(1);

}

if (argc <= 1)

{

out = fopen(temp_exe, "wb");

if (out == NULL)

{

fprintf(stderr, "Error writing to file \'%s\'\n", temp_exe);

fprintf(stderr, usage, argv[0]);

exit(1);

}

fseek(myself, MY_LENGTH, SEEK_SET);

while (bytesin = fread(buf, 1, sizeof(buf), myself))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(myself);

fclose(out);

fprintf(stderr, "copied %d bytes\n", totalbytes);

if (totalbytes == 0)

{

fprintf(stderr, "No data to un-bind in \'%s\'\n", argv[0]);

fprintf(stderr, usage, argv[0]);

exit(1);

}

{

HANDLE hProcess;

HANDLE hThread;

PROCESS_INFORMATION PI;

STARTUPINFO SI;

memset(&SI, 0, sizeof(SI));

SI.cb = sizeof(SI);

CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,

NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);

hProcess = PI.hProcess;

hThread = PI.hThread;

WaitForSingleObject(hProcess, INFINITE);

}

unlink(temp_exe);

}

else if (argc == 3)

{

out = fopen(argv[2], "wb");

if (out == NULL)

{

fprintf(stderr, "Error writing to file \'%s\'\n", out);

fprintf(stderr, usage, argv[0]);

exit(1);

}

fseek(myself, 0, SEEK_SET);

while (bytesin = fread(buf, 1, sizeof(buf), myself))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(myself);

in = fopen(argv[1], "rb");

if (in == NULL)

{

fprintf(stderr, "Error opening file \'%s\'\n", argv[1]);

fprintf(stderr, usage, argv[0]);

exit(1);

}

while (bytesin = fread(buf, 1, sizeof(buf), in))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(in);

fclose(out);

}

else

{

fprintf(stderr, usage, argv[0]);

exit(1);

}

}

Comment

From: krydea

Date: 03/11/2001 10:55AM PST

thx,

i can't add point's EE don't whant that.

but i can give more point's when i accept a answer!

say how mutch..

or i give you now 300 point's

Comment

From: krydea

Date: 03/11/2001 11:20AM PST

btw: if i run that bound file it only start's the binder!

??

what did you are i rong?

Comment

From: alexcohn

Date: 03/11/2001 11:40PM PST

Are you satisfied with one-executable binding?

I suggest that you open a separate request for icon "stealing", maybe somebody has a ready piece of

code for this. Anyway, I can look for a solution for this only tomorrow.

Regarding the last question,

> if i run that bound file it only start's the binder!

> what did you are i rong?

my fault - fix the usage:

char usage[] = "\nUsage:\n%s : to unbind and execute bound application;\n"

"%s somename.exe bound.exe : to bind executable somename.exe\n";

And do not forget to fix the constant

#define MY_LENGTH 30208

build the .exe once; look at its size; and replace 30208 with your size.

Comment

From: krydea

Date: 03/12/2001 01:19AM PST

what i whant is

bindt the binder programme to the a exe and when you run the new exe they both start.

is this posible?

btw: i will give you 400 point's if you expane some thing and help me with the ico

btw:is that reasonable?

btw: i use mvc++6.0

my e_mail: krydea@hotmail.com

Comment

From: alexcohn

Date: 03/12/2001 04:36AM PST

"They both start" - you mean the "big" exe starts, launches the adopted exe, and continues its work,

without waiting for the adopted exe to complete?

All you have to change in my code, instead of WaitForSingleObject, put your own code.

Or you mean you want to bind multiple executables?

Comment

From: krydea

Date: 03/13/2001 08:47AM PST

i whan to bind to exe's and wen you start the new one the 2 rogrammes start both.

how you call it i don't know!

Comment

From: DanRollins

Date: 03/13/2001 11:29AM PST

I think krydea wants Binder.exe to generate a program (Bound.exe) that contains two other programs (Prog1.exe

and Prog2.exe). When Bound.exe runs, it unbinds and starts both Prog1.exe and Prog2.exe

I further guess that once Prog1.exe and Prog2.exe are both running, Bound.Exe can close itself.

Is that correct krydea?

-- Dan

Comment

From: krydea

Date: 03/13/2001 10:51PM PST

yea that's is correct. unbind does not have to but they have to run both. wel executing bound.exe.

Comment

From: alexcohn

Date: 03/14/2001 02:50AM PST

OK. Is the following your req?

create binder.exe with the following command line parameters (on win95 or higher or NT4 or higher):

binder.exe prog1.exe prog2.exe bound.exe

generates from two existing arbitrary prog1.exe and prog2.exe, a new file bound.exe so that:

- the Windows icon for bound.exe is identical to prog1.exe

- bound.exe may be copied to any location

- when bound.exe runs, two programs start in parallel: prog1.exe and prog2.exe.

Comment

From: alexcohn

Date: 03/14/2001 06:42AM PST

Hey, the project is kind of heavy; it includes RC file, a special ICO file, and a C file. I'll be able

to send it to you on 20th - I'll be far from my computer this weekend. In the meanwhile, check the spec

above.

Proposed Answer

From: alexcohn

Date: 03/27/2001 11:52AM PST

/*****

I'm posting the answer C code here. You actually asked for C++, but I hope that old plain C will be

OK. Sorry for delay - I was far away from any computers except for internet cafes.

Add the following file: a.rc with one line as follows:

1 ICON "icon1.ico"

Note that the icon file should include at least all standard icon types (32x32x16, 16x16x16, 32x32x2,

32x32x256, 16x16x256), but the more the better.

To compile: cl a.c a.res

I used both MSVC 4.2 and 6.0, and win2K works just as well as win98.

******/

// file = a.c

#include <stdio.h>

#include <string.h>

#include <windows.h>

#include <sys/stat.h>

//#define DEBUG_PRINT

#pragma pack(1)

typedef struct ICONRESDIR {

BYTE Width;

BYTE Height;

BYTE ColorCount;

BYTE reserved;

} ICONRESDIR;

typedef struct tagRESDIR {

// union {

ICONRESDIR Icon;

// CURSORDIR Cursor;

// } ResInfo;

WORD Planes;

WORD BitCount;

DWORD BytesInRes;

WORD IconCursorId;

} RESDIR;

typedef struct NEWHEADER {

WORD Reserved;

WORD ResType;

WORD ResCount;

} NEWHEADER, *PNEWHEADER;

struct MODIFY_DATA {

unsigned int finder; // constant

_off_t my_length; // modifyed on the fly

} modify_data = {0x12345678, 0};

_off_t prog1_length = 0;

char my_name[MAX_PATH] = "abcdefghijklmnop";

char *his_name = NULL;

BYTE *buf = NULL;

int print_usage()

{

char *my_shortname = strrchr(my_name, '\\') + 1;

if (0 == modify_data.my_length) // bind

fprintf(stderr, "\nUsage:\n"

"%s prog1.exe prog2.exe bound.exe : to bind 2 executables\n", my_shortname);

else

fprintf(stderr, "\nUsage:\n"

"%s : to unbind and execute bound applications;\n", my_shortname);

exit(1);

return 0;

}

void create_process(const char* temp_exe, BOOL async)

{

HANDLE hProcess;

HANDLE hThread;

PROCESS_INFORMATION PI;

STARTUPINFO SI;

memset(&SI, 0, sizeof(SI));

SI.cb = sizeof(SI);

CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,

NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);

hProcess = PI.hProcess;

hThread = PI.hThread;

if (!async)

{

WaitForSingleObject(hProcess, INFINITE);

unlink(temp_exe);

}

}

void unbind_and_run()

{

FILE* myself;

FILE* out;

int bytesin;

int totalbytes = 0;

char temp_exe1[] = "temp1.exe";

char temp_exe2[] = "temp2.exe";

buf = (BYTE*)malloc(modify_data.my_length);

myself = fopen(my_name, "rb");

if (myself == NULL)

{

fprintf(stderr, "Error opening file \'%s\'\n", my_name);

print_usage();

}

out = fopen(temp_exe1, "wb");

if (out == NULL)

{

fprintf(stderr, "Error writing to file \'%s\'\n", temp_exe1);

print_usage();

}

fseek(myself, modify_data.my_length, SEEK_SET);

if (fread(&prog1_length, sizeof(prog1_length), 1, myself) == 0)

{

fprintf(stderr, "Error parsing file \'%s\'\n", my_name);

print_usage();

}

while (bytesin = fread(buf, 1, sizeof(buf), myself))

{

if (totalbytes + bytesin > prog1_length)

bytesin = prog1_length - totalbytes;

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(out);

#ifdef DEBUG_PRINT

fprintf(stderr, "copied %d bytes\n", totalbytes);

#endif DEBUG_PRINT

totalbytes = 0;

out = fopen(temp_exe2, "wb");

if (out == NULL)

{

fprintf(stderr, "Error writing to file \'%s\'\n", temp_exe2);

print_usage();

}

fseek(myself, modify_data.my_length + sizeof(modify_data.my_length) + prog1_length, SEEK_SET);

while (bytesin = fread(buf, 1, sizeof(buf), myself))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(out);

#ifdef DEBUG_PRINT

fprintf(stderr, "copied %d bytes\n", totalbytes);

#endif DEBUG_PRINT

fclose(myself);

if (totalbytes == 0)

{

fprintf(stderr, "No data to un-bind in \'%s\'\n", my_name);

print_usage();

}

create_process(temp_exe1, TRUE);

create_process(temp_exe2, TRUE);

}

BOOL check_args(int argc)

{

if (0 == modify_data.my_length) // bind

{

if (argc == 4)

return TRUE;

}

else

{

if (argc == 1)

return FALSE;

}

return print_usage();

}

typedef struct {

const RESDIR* pcResDir;

BYTE* pMatchIcon;

} my_enum_res_callback_data;

BOOL CALLBACK my_enum_res_callback(

HMODULE hExe, // module handle

LPCTSTR lpszType, // resource type

LPTSTR lpszName, // resource name

LPARAM lParam // application-defined parameter

)

{

HRSRC hRsrc = 0;

HGLOBAL hMem;

DWORD nDataLen;

NEWHEADER* pDirHeader;

RESDIR* pResDir;

BYTE* pData;

unsigned int k;

my_enum_res_callback_data* pMyDataStruct = (my_enum_res_callback_data*)lParam;

hRsrc = FindResource(hExe, lpszName, RT_GROUP_ICON);

hMem = LoadResource(hExe, hRsrc);

pDirHeader = (NEWHEADER*)LockResource(hMem);

pResDir = (RESDIR*)(pDirHeader+1);

for (k = 0; k < pDirHeader->ResCount; k++)

{

if (pResDir[k].BytesInRes == pMyDataStruct->pcResDir->BytesInRes &&

pResDir[k].BitCount == pMyDataStruct->pcResDir->BitCount &&

pResDir[k].Planes == pMyDataStruct->pcResDir->Planes &&

memcmp(&pResDir[k].Icon, &pMyDataStruct->pcResDir->Icon, sizeof(pResDir->Icon)) == 0)

{

hRsrc = FindResource(hExe, MAKEINTRESOURCE(pResDir[k].IconCursorId), RT_ICON);

hMem = LoadResource(hExe, hRsrc );

nDataLen = SizeofResource( hExe, hRsrc );

pData = LockResource(hMem);

#ifdef DEBUG_PRINT

fprintf(stderr, "\tfound %d-th icon in dir %d with ID=%d (size %d)\n",

k, lpszName, pResDir[k].IconCursorId, nDataLen);

#endif DEBUG_PRINT

pMyDataStruct->pMatchIcon = pData;

return FALSE; // stop enumeration

}

}

return TRUE;

}

BYTE* find_match_icon(const RESDIR* pcResDir)

{

HMODULE hExe;

my_enum_res_callback_data myDataStruct;

myDataStruct.pMatchIcon = NULL;

myDataStruct.pcResDir = pcResDir;

hExe = LoadLibraryEx(his_name, NULL, LOAD_LIBRARY_AS_DATAFILE);

if (hExe == 0)

{

fprintf(stderr, "cannot load file \'%s\' to find an icon\n", his_name);

return NULL;

}

if (EnumResourceNames(hExe, RT_GROUP_ICON, my_enum_res_callback, (LPARAM)&myDataStruct) == 0 &&

myDataStruct.pMatchIcon == 0)

{

fprintf(stderr, "cannot find icon directory in file \'%s\'\n", his_name);

}

return myDataStruct.pMatchIcon;

}

list_my_icons()

{

HRSRC hRsrc;

const HMODULE hExe = 0; // means load from this module

HGLOBAL hMem;

DWORD nDataLen = 0;

NEWHEADER* pDirHeader;

RESDIR* pResDir;

unsigned int i, k, n;

hRsrc = FindResource(hExe, MAKEINTRESOURCE(1), RT_GROUP_ICON);

hMem = LoadResource(hExe, hRsrc );

nDataLen = SizeofResource( hExe, hRsrc );

pDirHeader = (NEWHEADER*)LockResource(hMem);

pResDir = (RESDIR*)(pDirHeader+1);

for (i = 0; i < modify_data.my_length - nDataLen; i++)

{

for (k = 0; k < nDataLen; k++)

{

if (buf[i+k] != ((BYTE*)pDirHeader)[k])

break;

}

if (k == nDataLen)

break;

}

for (n = 0; n < pDirHeader->ResCount; n++)

{

DWORD nDataLen = 0;

BYTE* pData;

unsigned int i, k;

hRsrc = FindResource(hExe, MAKEINTRESOURCE(pResDir[n].IconCursorId), RT_ICON);

hMem = LoadResource(hExe, hRsrc );

nDataLen = SizeofResource( hExe, hRsrc );

#ifdef DEBUG_PRINT

fprintf(stderr, "Icon found: %d[%d bytes] %dx%dx%d; %d bytes loaded.\n",

pResDir[n].IconCursorId, pResDir[n].BytesInRes,

pResDir[n].Icon.Width, pResDir[n].Icon.Height, pResDir[n].Icon.ColorCount, nDataLen);

#endif DEBUG_PRINT

pData= (BYTE*)LockResource(hMem);

for (i = 0; i < modify_data.my_length - nDataLen; i++)

{

for (k = 0; k < nDataLen; k++)

{

if (buf[i+k] != pData[k])

break;

}

if (k == nDataLen)

{

BYTE* pMatchIcon = NULL;

if (pMatchIcon = find_match_icon(pResDir+n))

memcpy(buf+i, pMatchIcon, nDataLen);

else

{

#ifdef DEBUG_PRINT

fprintf(stderr, "\tNo fit.\n");

#endif DEBUG_PRINT

pResDir[n].BytesInRes = 0;

}

break;

}

}

}

k = pDirHeader->ResCount;

pDirHeader->ResCount = 0; // count again

for (n = 0; n < k; n++)

{

if (pResDir[n].BytesInRes != 0)

{

if (pDirHeader->ResCount != n)

{

memcpy(&pResDir[pDirHeader->ResCount], &pResDir[n], sizeof(pResDir[n]));

}

pDirHeader->ResCount++;

}

}

#ifdef DEBUG_PRINT

fprintf(stderr, "Final: %d icons, \n", pDirHeader->ResCount);

for (n = 0; n < pDirHeader->ResCount; n++)

{

fprintf(stderr, "\tid=%d[%d bytes] %dx%dx%d\n",

pResDir[n].IconCursorId, pResDir[n].BytesInRes,

pResDir[n].Icon.Width, pResDir[n].Icon.Height, pResDir[n].Icon.ColorCount);

}

#endif DEBUG_PRINT

memcpy(buf+i, pDirHeader, nDataLen); // wipe unfound icons from the directory

}

void bind_files(int argc, char** argv)

{

FILE* myself;

FILE* out;

FILE* in;

int bytesin;

int totalbytes = 0;

struct stat ST;

unsigned int finder = 0x12345678;

unsigned int i, k;

his_name = argv[1];

stat(my_name, &ST);

modify_data.my_length = ST.st_size;

if (modify_data.my_length == 0)

{

fprintf(stderr, "Error opening file \'%s\'\n", my_name);

print_usage();

}

buf = malloc(modify_data.my_length);

if (buf == NULL)

{

fprintf(stderr, "Error opening file \'%s\'\n", my_name);

print_usage();

}

myself = fopen(my_name, "rb");

if (myself == NULL)

{

free(buf);

fprintf(stderr, "Error opening file \'%s\'\n", my_name);

print_usage();

}

bytesin = fread(buf, 1, modify_data.my_length, myself);

fclose(myself);

if (bytesin != modify_data.my_length)

{

free(buf);

fprintf(stderr, "cannot read full file: read %d bytes of %d", bytesin, modify_data.my_length);

print_usage();

}

for (i = 0; i < modify_data.my_length - sizeof(finder); i += sizeof(finder))

{

for (k = 0; k < sizeof(finder); k++)

{

if (buf[i+k] != ((BYTE*)&finder)[k])

break;

}

if (k == sizeof(finder))

{

memcpy(buf+ i, &modify_data, sizeof(modify_data));

break;

}

}

if (i >= modify_data.my_length - sizeof(finder))

{

free(buf);

fprintf(stderr, "Cannot find the place to set my size\n");

print_usage();

}

if (0 != stat(argv[1], &ST) || ST.st_size == 0)

{

free(buf);

fprintf(stderr, "Error opening file \'%s\'\n", argv[1]);

print_usage();

}

list_my_icons();

out = fopen(argv[argc-1], "wb");

if (out == NULL)

{

free(buf);

fprintf(stderr, "Error writing to file \'%s\'\n", out);

print_usage();

}

totalbytes += fwrite(buf, 1, bytesin, out);

in = fopen(argv[1], "rb");

if (in == NULL)

{

free(buf);

fprintf(stderr, "Error opening file \'%s\'\n", argv[1]);

print_usage();

}

totalbytes += fwrite(&ST.st_size, 1, sizeof(ST.st_size), out);

while (bytesin = fread(buf, 1, modify_data.my_length, in))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(in);

in = fopen(argv[2], "rb");

if (in == NULL)

{

free(buf);

fprintf(stderr, "Error opening file \'%s\'\n", argv[2]);

print_usage();

}

while (bytesin = fread(buf, 1, modify_data.my_length, in))

{

totalbytes += fwrite(buf, 1, bytesin, out);

}

fclose(in);

fclose(out);

free(buf);

}

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

{

BOOL bind = FALSE;

// my_name = argv[0];

GetModuleFileName(0, my_name, sizeof(my_name));

bind = check_args(argc);

if (bind)

bind_files(argc, argv);

else

unbind_and_run();

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有