selfext-user Mailing List for SelfExt - Cab self extract and execute
Brought to you by:
mweth
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
(7) |
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ben...@id...> - 2004-05-22 12:08:20
|
Dear Open Source developer I am doing a research project on "Fun and Software Development" in which I kindly invite you to participate. You will find the online survey under http://fasd.ethz.ch/qsf/. The questionnaire consists of 53 questions and you will need about 15 minutes to complete it. With the FASD project (Fun and Software Development) we want to define the motivational significance of fun when software developers decide to engage in Open Source projects. What is special about our research project is that a similar survey is planned with software developers in commercial firms. This procedure allows the immediate comparison between the involved individuals and the conditions of production of these two development models. Thus we hope to obtain substantial new insights to the phenomenon of Open Source Development. With many thanks for your participation, Benno Luthiger PS: The results of the survey will be published under http://www.isu.unizh.ch/fuehrung/blprojects/FASD/. We have set up the mailing list fa...@we... for this study. Please see http://fasd.ethz.ch/qsf/mailinglist_en.html for registration to this mailing list. _______________________________________________________________________ Benno Luthiger Swiss Federal Institute of Technology Zurich 8092 Zurich Mail: benno.luthiger(at)id.ethz.ch _______________________________________________________________________ |
|
From: Mike W. <mik...@nt...> - 2003-09-13 16:24:41
|
On Saturday 13 September 2003 4:32 pm, Mike Wetherell wrote: > Below is a tiny module which defines 'new' and 'delete' which you > can use if you want to write C++ without standard libs. I'm releasing it under the GPL BTW. I forgot to say what the license should be. Mike |
|
From: Mike W. <mik...@nt...> - 2003-09-13 15:32:53
|
On Saturday 13 September 2003 9:41 am, Ho Kei Lau wrote:
> Thanks for your help.. I'm now working on an SFX without C libraries, C++
> classes... what a headache!
I'm not sure if I've understood you correctly. Presumably that means you wish
you could use the C runtime and C++ libs while working on selfext? or did you
mean you want a self extractor with no depenancies?
If it's the former, then you can link to the C runtime or C++ libs if you
want to. Obviously a self extractor shouldn't depend on any dlls that won't
already be installed on the users machine. So your choices are:
For the C runtime:
1. Do without. The Windows API has an equivalent for just about everything
that you'll find in a CRT.
2. Dynamically link. This will give you a program that depends on MSVCRT.DLL
which is present on all 32-bit verisons of Windows except the first release
of Windows 95.
3. Statically link. Ok but the executable will be larger.
For C++ library:
1. Do without. If you include implementations of 'new' and 'delete' (see
below) then you can write C++ code normally, though no exceptions or rtti or
library classes like std::string.
2. Dynamically link. Not realistic, different versions of Windows and VC++
come with different dlls.
3. Statically link. Ok but the executable will be larger.
Below is a tiny module which defines 'new' and 'delete' which you
can use if you want to write C++ without standard libs.
You can use this module even if you link to the the standard libs, and it will
still reduce the size of your executable by replacing the standard startup
code. This can be useful if you just want a few functions from the standard
libs, though of course anything that needs to have been initialized by the
startup code (like stdio) isn't going to work.
HTH,
Mike
//////////////////////////////////////////////////////////////////////
// Minimal startup and memory functions for programs that don't
// want to link in the runtime library. Define MCRT_FULL if you're
// going to use the command line parameter of WinMain.
//
// Build Options:
//
// Release Link: Ignore all default libraries (optional)
// C++ Language: Disable exception handling ('fraid so)
//
#include <windows.h>
static HANDLE ghHeap; // processes's heap handle
extern "C" void __cdecl main(void) {} // linker complains without this
//////////////////////////////////////////////////////////////////////
// Startup code (extra lean)
#ifndef MCRT_FULL
extern "C" void __cdecl WinMainCRTStartup(void)
{
ghHeap = GetProcessHeap();
ExitProcess(WinMain(GetModuleHandle(NULL), NULL, NULL, SW_SHOWDEFAULT));
}
#endif // !MCRT_FULL
//////////////////////////////////////////////////////////////////////
// Startup code (full)
#ifdef MCRT_FULL
extern "C" void __cdecl WinMainCRTStartup(void)
{
int mainret;
char *lpCmdLine;
STARTUPINFO StartupInfo;
ghHeap = GetProcessHeap();
lpCmdLine = GetCommandLine();
// Skip past program name (first token in command line).
if (*lpCmdLine == '"')
{
while (*lpCmdLine && (*lpCmdLine != '"'))
lpCmdLine++;
if (*lpCmdLine == '"')
lpCmdLine++;
}
else
{
while (*lpCmdLine > ' ')
lpCmdLine++;
}
// Skip past any white space preceeding the second token.
while (*lpCmdLine && (*lpCmdLine <= ' '))
lpCmdLine++;
StartupInfo.dwFlags = 0;
GetStartupInfo(&StartupInfo);
mainret = WinMain(
GetModuleHandle(NULL), NULL, lpCmdLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW ?
StartupInfo.wShowWindow : SW_SHOWDEFAULT);
ExitProcess(mainret);
}
#endif // MCRT_FULL
//////////////////////////////////////////////////////////////////////
// new and delete
void * __cdecl operator new(size_t cb)
{
return HeapAlloc(ghHeap, 0, cb);
}
void __cdecl operator delete(void *pv)
{
HeapFree(ghHeap, 0, pv);
}
//////////////////////////////////////////////////////////////////////
// malloc/free
void * __cdecl malloc(size_t cb)
{
return HeapAlloc(ghHeap, 0, cb);
}
void * __cdecl calloc(size_t n, size_t cb)
{
return HeapAlloc(ghHeap, 0, n * cb);
}
void * __cdecl realloc(void *p, size_t cb)
{
return p == NULL ? HeapAlloc(ghHeap, 0, cb) : HeapReAlloc(ghHeap, 0, p, cb);
}
void __cdecl free(void *p)
{
HeapFree(ghHeap, 0, p);
}
|
|
From: Mike W. <mik...@nt...> - 2003-09-13 02:14:47
|
Hi Kei,
The mailing list system seems a little slow, appologies for that. Hopefully
by now you will have received my previous reply (which includes a patch to do
this for you).
Please post in plain text rather than html, if your system allows it.
> Last night I've decided that removing 4 bytes is too much of a hassle
> because it requires the offset to be corrected at later Fileread incidents,
> so instead I've not altered the cabinet size, instead changing the first
> byte from 'M' to a NULL. This is enough to trick other archivers :)
If you remove the 4 bytes then subtract 4 from nOffset in Extract() before
the call to CheckValid(), though you're right, easier still is to modify them.
> This is the working code that I've got after struggling for a whole night..
> (g_iExeSize is the size of the EXE file, while g_bMutant is a BOOL which is
> true when we are dealing with the "mutant cabinet" (the Cabinet with a NULL
> in the first char))
You can use GetPtr() to get the offset to the cab's signature:
const file_struct *pfs = GetPtr(hf);
where file_struct is:
struct file_struct
{
HANDLE m_hFile; // the Windows file handle
int m_nOffset; // the offset to the cab's signature
};
> By the way... is there a way that I can extract data directly to memory or
> to a buffer instead of writing it physically to the disk? (Because the data
> is not supposed to be known by the user, it's for the SFX's internal use)
Yes you can do that. If you look at the switch statement in the notify()
function, 'case fdintCOPY_FILE' is called to open each output file and 'case
fdintCLOSE_FILE_INFO' is called to close it again. In between the
'file_write' function is called to write the data. So by replacing these
parts you can redirect the data somewhere else.
> I'd be glad if you can help me~
I'll do my best.
Mike
|
|
From: Ho K. L. <ywc...@ho...> - 2003-09-12 23:41:55
|
<html><div style='background-color:'><DIV>
<P>Last night I've decided that removing 4 bytes is too much of a hassle because it requires the offset to be corrected at later Fileread incidents, so instead I've not altered the cabinet size, instead changing the first byte from 'M' to a NULL. This is enough to trick other archivers :)</P>
<P>This is the working code that I've got after struggling for a whole night.. (g_iExeSize is the size of the EXE file, while g_bMutant is a BOOL which is true when we are dealing with the "mutant cabinet" (the Cabinet with a NULL in the first char))</P>
<P>By the way... is there a way that I can extract data directly to memory or to a buffer instead of writing it physically to the disk? (Because the data is not supposed to be known by the user, it's for the SFX's internal use)</P>
<P>I'd be glad if you can help me~ </P>
<P>Kei</P>
<P>
<HR>
</P>
<P><FONT face="Courier New, Courier, Monospace" size=2>FNREAD(file_read)<BR>{ <BR> DWORD rslt;<BR> int iPos = SetFilePointer(GetHandle(hf), 0, 0, FILE_CURRENT);<BR> if(iPos==g_iExeSize && g_bMutant)<BR> {<BR> char* cTmp = (char*) pv;<BR> ReadFile(GetHandle(hf), cTmp, cb, &rslt, NULL); <BR> cTmp[0]='M';<BR> return (rslt);</FONT></P>
<P><FONT face="Courier New, Courier, Monospace" size=1><FONT size=2> } else<BR> {<BR> ReadFile(GetHandle(hf), pv, cb, &rslt, NULL); <BR> return rslt; <BR> }<BR>}</FONT><BR></FONT></P>
<P><BR><BR> </P></DIV></div><br clear=all><hr>Add photos to your messages with <a href="http://g.msn.com/8HMCEN/2749??PS=">MSN 8. </a> Get 2 months FREE*.</html>
|
|
From: Mike W. <mik...@nt...> - 2003-09-12 19:37:24
|
On Friday 12 September 2003 10:38 am, Ho Kei Lau wrote:
> Hello, I would like to protect my SFX from being able to be opened by other
> archivers like WinZip. I want to do it simply by removing the first 4 bytes
> ("MSCF") from the cabinet, then in file_read(), add the 4 bytes to the
> buffer temporarily. I have tried to do this .. but seems it only retrieves
> the header information, but NOT extracting the files
> inside. FNREAD(file_read) {
> DWORD rslt;
> if(SetFilePointer(GetHandle(hf), 0, 0, FILE_CURRENT)==g_iExeSize+8)
> {
> char* cTmp = (char*) pv;
> lstrcpy(cTmp, "MSCF");
> ReadFile(GetHandle(hf), &cTmp[4], cb-4, &rslt, NULL);
> return (rslt+4);
> } else
> {
> ReadFile(GetHandle(hf), pv, cb, &rslt, NULL);
> return rslt;
> }
> }
> What's wrong? Can somebody please help me? Kei
I'm resending this since the first has disappeared, so appologies for the
duplicate if the original surfaces.
Hi Kei,
That's an interesting idea.
If you remove the 4 signature bytes (rather than just changing them), you
also need to subtract 4 from nOffset in Extract() so that all the seeking is
offset by 4 bytes.
Currently CheckValid() doesn't open the file using the 'filename|<nnnnnn>'
syntax to fake the start of the file, so a slight mod is needed there (see
below).
And then finally a change like you have there is needed to file_read().
You can get the offset to the start of the cab data within the executable
using GetPtr(hf) (see below).
Below is a patch for you that does this. I hope this helps, let me know if
you come across any difficulties applying it.
Mike
Index: ExtFdi.cpp
===================================================================
RCS file: /cvsroot/selfext/selfext/ExtFdi.cpp,v
retrieving revision 1.2
diff -u -2 -r1.2 ExtFdi.cpp
--- ExtFdi.cpp 18 Sep 2002 09:25:52 -0000 1.2
+++ ExtFdi.cpp 12 Sep 2003 18:48:22 -0000
@@ -204,5 +204,17 @@
{
DWORD rslt;
- ReadFile(GetHandle(hf), pv, cb, &rslt, NULL);
+
+ const file_struct *pfs = GetPtr(hf);
+
+ ReadFile(pfs->m_hFile, pv, cb, &rslt, NULL);
+
+ if (SetFilePointer(pfs->m_hFile, 0, 0, FILE_CURRENT) == pfs->m_nOffset + rslt)
+ {
+ if (cb > 4) cb = 4;
+ char *p = (char *)pv;
+ while (cb--)
+ p[cb] = "MSCF"[cb];
+ }
+
return rslt;
}
@@ -290,5 +302,8 @@
return LoadOsError(IDS_ERR_EXTRACTING, ERROR_CANCELLED);
- int hf = file_open((LPSTR)pszFilename, _O_BINARY|_O_RDONLY, 0);
+ CHAR szFile[MAX_PATH+11];
+ wsprintf(szFile, "%s|%d", pszFilename, nOffset);
+
+ int hf = file_open(szFile, _O_BINARY|_O_RDONLY, 0);
if (hf == -1)
return LoadOsError(IDS_ERR_EXTRACTING);
@@ -296,10 +311,4 @@
FDICABINETINFO fdici;
- if (file_seek(hf, nOffset, SEEK_SET) != nOffset)
- {
- LoadOsError(IDS_ERR_EXTRACTING);
- goto handle_error;
- }
-
if (!FDIIsCabinet(hfdi, hf, &fdici))
{
@@ -376,4 +385,6 @@
if (hfdi == NULL)
return LoadError(IDS_ERR_CABINIT, IDS_FDIERROR_NONE + erf.erfOper);
+
+ nOffset -= 4;
// check the file is a valid cabinet
|
|
From: Mike W. <mik...@nt...> - 2003-09-12 19:21:58
|
On Friday 12 September 2003 10:38 am, Ho Kei Lau wrote:
> Hello, I would like to protect my SFX from being able to be opened by other
> archivers like WinZip. I want to do it simply by removing the first 4 bytes
> ("MSCF") from the cabinet, then in file_read(), add the 4 bytes to the
> buffer temporarily. I have tried to do this .. but seems it only retrieves
> the header information, but NOT extracting the files
> inside. FNREAD(file_read) {
> DWORD rslt;
> if(SetFilePointer(GetHandle(hf), 0, 0, FILE_CURRENT)==g_iExeSize+8)
> {
> char* cTmp = (char*) pv;
> lstrcpy(cTmp, "MSCF");
> ReadFile(GetHandle(hf), &cTmp[4], cb-4, &rslt, NULL);
> return (rslt+4);
> } else
> {
> ReadFile(GetHandle(hf), pv, cb, &rslt, NULL);
> return rslt;
> }
> }
> What's wrong? Can somebody please help me? Kei
Hi Kei,
That's an interesting idea.
If you remove the 4 signature bytes (rather than just changing them), you
also need to subtract 4 from nOffset in Extract() so that all the seeking is
offset by 4 bytes.
Currently CheckValid() doesn't open the file using the 'filename|<nnnnnn>'
syntax to fake the start of the file, so a slight mod is needed there (see
below).
And then finally a change like you have there is needed to file_read().
You can get the offset to the start of the cab data within the executable
using GetPtr(hf) (see below).
Below is a patch for you that does this. I hope this helps, let me know if
you come across any difficulties applying it.
Mike
Index: ExtFdi.cpp
===================================================================
RCS file: /cvsroot/selfext/selfext/ExtFdi.cpp,v
retrieving revision 1.2
diff -u -2 -r1.2 ExtFdi.cpp
--- ExtFdi.cpp 18 Sep 2002 09:25:52 -0000 1.2
+++ ExtFdi.cpp 12 Sep 2003 18:48:22 -0000
@@ -204,5 +204,17 @@
{
DWORD rslt;
- ReadFile(GetHandle(hf), pv, cb, &rslt, NULL);
+
+ const file_struct *pfs = GetPtr(hf);
+
+ ReadFile(pfs->m_hFile, pv, cb, &rslt, NULL);
+
+ if (SetFilePointer(pfs->m_hFile, 0, 0, FILE_CURRENT) == pfs->m_nOffset + rslt)
+ {
+ if (cb > 4) cb = 4;
+ char *p = (char *)pv;
+ while (cb--)
+ p[cb] = "MSCF"[cb];
+ }
+
return rslt;
}
@@ -290,5 +302,8 @@
return LoadOsError(IDS_ERR_EXTRACTING, ERROR_CANCELLED);
- int hf = file_open((LPSTR)pszFilename, _O_BINARY|_O_RDONLY, 0);
+ CHAR szFile[MAX_PATH+11];
+ wsprintf(szFile, "%s|%d", pszFilename, nOffset);
+
+ int hf = file_open(szFile, _O_BINARY|_O_RDONLY, 0);
if (hf == -1)
return LoadOsError(IDS_ERR_EXTRACTING);
@@ -296,10 +311,4 @@
FDICABINETINFO fdici;
- if (file_seek(hf, nOffset, SEEK_SET) != nOffset)
- {
- LoadOsError(IDS_ERR_EXTRACTING);
- goto handle_error;
- }
-
if (!FDIIsCabinet(hfdi, hf, &fdici))
{
@@ -376,4 +385,6 @@
if (hfdi == NULL)
return LoadError(IDS_ERR_CABINIT, IDS_FDIERROR_NONE + erf.erfOper);
+
+ nOffset -= 4;
// check the file is a valid cabinet
|
|
From: Ho K. L. <ywc...@ho...> - 2003-09-12 09:39:13
|
<html><div style='background-color:'><DIV>Hello,</DIV>
<DIV> </DIV>
<DIV>I would like to protect my SFX from being able to be opened by other archivers like WinZip. I want to do it simply by removing the first 4 bytes ("MSCF") from the cabinet, then in file_read(), add the 4 bytes to the buffer temporarily. I have tried to do this .. but seems it only retrieves the header information, but NOT extracting the files inside.</DIV>
<DIV> </DIV>
<DIV>FNREAD(file_read)<BR>{ <BR> DWORD rslt;<BR> if(SetFilePointer(GetHandle(hf), 0, 0, FILE_CURRENT)==g_iExeSize+8)<BR> {<BR> char* cTmp = (char*) pv;<BR> lstrcpy(cTmp, "MSCF");<BR> ReadFile(GetHandle(hf), &cTmp[4], cb-4, &rslt, NULL); <BR> return (rslt+4);<BR> } else<BR> {<BR> ReadFile(GetHandle(hf), pv, cb, &rslt, NULL); <BR> return rslt; <BR> }<BR>}<BR></DIV>
<DIV>What's wrong? Can somebody please help me?</DIV>
<DIV> </DIV>
<DIV>Kei</DIV>
<DIV> </DIV></div><br clear=all><hr>Tired of spam? Get <a href="http://g.msn.com/8HMGEN/2734??PS=">advanced junk mail protection</a> with MSN 8.</html>
|
|
From: M.J.Wetherell <chi...@us...> - 2003-06-16 22:40:13
|
On Monday 16 June 2003 10:45 pm, David Austin wrote: > In other words, that solved it. > Great, I'm glad that was it. > I can't suggest a way to > have a "one size fits v6 and v7 of VS", other than documenting this switch. > Yeah, I think that's what I'll do. Thanks, Mike |
|
From: M.J.Wetherell <chi...@us...> - 2003-06-16 20:36:36
|
On Sunday 15 June 2003 8:51 pm, David Austin wrote: > > ExtCab.obj : error LNK2019: unresolved external symbol ___security_cookie Thanks for pointing that out. I don't have a copy of VC++ 7, but I'd like to make it so that it can compile on it without changes. I dug this up on Google: > ___security_cookie is a global CRT DWORD, initialized with a "random" > value, used for "/GS" (Buffer Security Check) option implementation. > Are you linking against the correct libraries? (It's just a guess...) > You can try to disable "Buffer Security Check" in properties --> c/c++ > --> Code Generation --> Buffer Security Check. > So can you try disabling 'Buffer Security Check' as described, it must require support from the C runtime library, which we're not linking against to keep the program size small. Let me know if that solves it, I'd like to incorporate the fix into the distribution. I'm not sure how, though: if I ship VC++ 7 project files then people with earlier compilers won't be able to compile it, any suggestions? Thanks Mike |
|
From: David A. <Da...@Sp...> - 2003-06-15 19:53:06
|
Dear List:
I am a VB6 programmer using SelfExt to package install programs. I need to
make a small customization to SelfExt which I believe I can stumble my way
through on. However, using VS .NET (I don't have VS6 C++, just VB6), the
totally unmodified source build gives the following Linker errors which I
am unable to get past. The LNK2019 message talks about:
For C++ projects from previous releases that were upgraded to the current
version, if __UNICODE was defined and the entry point was WinMain, you need
to change the name for the entry point function to either _tWinMain or _tmain
I suspect my solution lies in this area, but I am unable to determine the
needed modifications. Can anyone help?
Linker error messages:
ExtCab.obj : error LNK2019: unresolved external symbol ___security_cookie
referenced in function "int __cdecl chiclero::Extract(char const *,int,char
const *,char *,struct HWND__ *,unsigned int)"
(?Extract@chiclero@@YAHPBDH0PADPAUHWND__@@I@Z)
SelfExt.obj : error LNK2019: unresolved external symbol ___security_cookie
referenced in function _WinMain@16
Worker.obj : error LNK2001: unresolved external symbol ___security_cookie
ExtCab.obj : error LNK2019: unresolved external symbol
@__security_check_cookie@4 referenced in function "int __cdecl
chiclero::Extract(char const *,int,char const *,char *,struct HWND__
*,unsigned int)" (?Extract@chiclero@@YAHPBDH0PADPAUHWND__@@I@Z)
SelfExt.obj : error LNK2019: unresolved external symbol
@__security_check_cookie@4 referenced in function _WinMain@16
Worker.obj : error LNK2001: unresolved external symbol
@__security_check_cookie@4
.\Release/SelfExt.exe : fatal error LNK1120: 2 unresolved externals
From selfext.cpp area of probable problem:
//////////////////////////////////////////////////////////////////////
// Replacement startup code, so that it is not necessary to link with
// the run-time library
extern "C" void __cdecl WinMainCRTStartup(void) {
ExitProcess(WinMain(GetModuleHandle(NULL), NULL, "", SW_SHOWDEFAULT));
}
#ifdef _MSC_VER // MS linker complains without this
extern "C" void __cdecl main(void) { }
#endif
namespace std {
extern "C" void * __cdecl memset(void *s, int c, size_t n) {
for (size_t i = 0; i < n; i++)
((char*)s)[i] = c;
return s;
}
}
//////////////////////////////////////////////////////////////////////
// WinMain
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE /*hPrevInstance*/,
LPSTR /*lpCmdLine*/,
int /*nCmdShow*/ )
{
Much thanks for any insights, David Austin
|