Private string inside C code.
After a lot of messing around, time consumption and jiggery-pokery I finally got a common piece of code for this thread working:
The OP wanted the string to be alone and as close to the top of the code as possible and not inside the data section.
Well, I wanted to make it possible for AMIGA users to have the same as we UNIX users, and upload to AMINET to suit.
But when it compiled in gcc 2.95.3 i got some warnings and errors, etc... When the warnings and errors went the test code similar to the URL above inverted everything and the data section was at the top and the private string was below the data section. After much thought this was the demo code that worked for the platforms tested on.
The assembly code does not need to be changed at all as the 2 instructions are the same for both architectures.
/* embed_private_string.c */
/* Guaranteed to allow up to 120 ASCII characters inside a function using gcc. */
/* It IS easily possible to get many, many more characters but this is a minimal approach. */
/* Without any modifications this will compile on these platforms:- */
/* Works on gcc 2.95.3 for the classic AMIGA OS 3.0.x using ADE the *NIX emulator, Motorola 68000+ architecture. */
/* Works on gcc 4.2.1 for OSX 10.14.x, 64 bit, Intel architecture. */
/* Works on gcc 7.3.0 for Linux Mint 19, 64 bit, Intel architecture. */
/* -- I have no idea whether this compiles on the current gcc 8.2.0, 20-02-2019. -- */
#include <stdio.h>
void Private_String(void)
{
/* To keep this string near the top of the code this must be the first function. */
/* This string will always be separate from the normal data section. */
/* It MUST be an EVEN number of characters long, including a single */
/* newline and the required NULL padding characters at the end. */
asm(" jmp exit_asm;"
"string:"
" .asciz \"'$VER (C)_Barry_Walker_CC0_Licence_[PD].'\\n\\0\";"
"exit_asm:"
" nop;");
/* IMPORTANT! DO NOT use the assembler RETURN instruction at all! */
return;
}
/* All further strings will be stored in the data section area. */
void Test_Function(void)
{
/* This function is just a test function. */
printf("\nA test function to check that the strings are in the data section.\n");
return;
}
int main(void)
{
/* Note: Private_String() does absolutely NOTHING. */
Private_String();
Test_Function();
printf("\nThese strings should be in the data section.\n");
printf("The hidden string is inside the code section.\n");
printf("'$VER (C)_Barry_Walker_CC0_Licence_[PD].'\n\n");
return 0;
}
Results for OSX 10.14.x:
00000e00 55 48 89 e5 e9 2c 00 00 00 27 24 56 45 52 20 28 |UH...,...'$VER (|
00000e10 43 29 5f 42 61 72 72 79 5f 57 61 6c 6b 65 72 5f |C)_Barry_Walker_|
00000e20 43 43 30 5f 4c 69 63 65 6e 63 65 5f 5b 50 44 5d |CC0_Licence_[PD]|
00000e30 2e 27 0a 00 00 90 5d c3 0f 1f 84 00 00 00 00 00 |.'....].........|
00000e40 55 48 89 e5 48 83 ec 10 48 8d 3d 87 00 00 00 b0 |UH..H...H.=.....|
00000e50 00 e8 60 00 00 00 89 45 fc 48 83 c4 10 5d c3 90 |..`....E.H...]..|
00000e60 55 48 89 e5 48 83 ec 10 c7 45 fc 00 00 00 00 e8 |UH..H....E......|
00000e70 8c ff ff ff e8 c7 ff ff ff 48 8d 3d 9b 00 00 00 |.........H.=....|
00000e80 b0 00 e8 2f 00 00 00 48 8d 3d bc 00 00 00 89 45 |.../...H.=.....E|
00000e90 f8 b0 00 e8 1e 00 00 00 48 8d 3d da 00 00 00 89 |........H.=.....|
00000ea0 45 f4 b0 00 e8 0d 00 00 00 31 c9 89 45 f0 89 c8 |E........1..E...|
00000eb0 48 83 c4 10 5d c3 ff 25 54 01 00 00 4c 8d 1d 45 |H...]..%T...L..E|
00000ec0 01 00 00 41 53 ff 25 35 01 00 00 90 68 00 00 00 |...AS.%5....h...|
00000ed0 00 e9 e6 ff ff ff 0a 41 20 74 65 73 74 20 66 75 |.......A test fu|
00000ee0 6e 63 74 69 6f 6e 20 74 6f 20 63 68 65 63 6b 20 |nction to check |
00000ef0 74 68 61 74 20 74 68 65 20 73 74 72 69 6e 67 73 |that the strings|
00000f00 20 61 72 65 20 69 6e 20 74 68 65 20 64 61 74 61 | are in the data|
00000f10 20 73 65 63 74 69 6f 6e 2e 0a 00 0a 54 68 65 73 | section....Thes|
00000f20 65 20 73 74 72 69 6e 67 73 20 73 68 6f 75 6c 64 |e strings should|
00000f30 20 62 65 20 69 6e 20 74 68 65 20 64 61 74 61 20 | be in the data |
00000f40 73 65 63 74 69 6f 6e 2e 0a 00 54 68 65 20 68 69 |section...The hi|
00000f50 64 64 65 6e 20 73 74 72 69 6e 67 20 69 73 20 69 |dden string is i|
00000f60 6e 73 69 64 65 20 74 68 65 20 63 6f 64 65 20 73 |nside the code s|
00000f70 65 63 74 69 6f 6e 2e 0a 00 27 24 56 45 52 20 28 |ection...'$VER (|
It looks much the same on all three OSes even though it was originally inverted on the AMIGA A1200.
It took wime to get it working, but this might be a better bet for drew77
as it is consistent on differing platforms and compiles on differing versions of gcc.
Have fun...
EDIT:
Off to give this to the AMINET site soon...
2 Likes
As a grand finale to this and the other thread, this I never realised; comments, jokes, passing remarks and function characteristics inside any and every function inside the executable itself.
I knew that the idea would work but not to this extent...
/* embed_private_string.c */
/* Guaranteed to allow up to 120 ASCII characters inside a function using gcc. */
/* It IS easily possible to get many, many more characters but this is a minimal approach. */
/* Without any modifications this will compile on these platforms:- */
/* Works on gcc 2.95.3 for the classic AMIGA OS 3.0.x using ADE the *NIX emulator, Motorola 68000+ architecture. */
/* Works on gcc 4.2.1 for OSX 10.14.x, 64 bit, Intel architecture. */
/* Works on gcc 7.3.0 for Linux Mint 19, 64 bit, Intel architecture. */
/* -- I have no idea whether this compiles on the current gcc 8.2.0, 20-02-2019. -- */
#include <stdio.h>
void Private_String(void)
{
/* To keep this string near the top of the code this must be the first function. */
/* This string will always be separate from the normal data section. */
/* It MUST be an EVEN number of characters long, including a */
/* single newline and the required NULL characters at the end. */
asm(" jmp exit_asm1;"
"string1:"
" .asciz \"'$VER (C)_Barry_Walker_CC0_Licence_[PD].'\\n\\0\";"
"exit_asm1:"
" nop;");
/* IMPORTANT! DO NOT use the assembler RETURN instruction at all! */
return;
}
void Test_Function(void)
{
/* The comment will be inside the function code, all other strings will be in the data section. */
asm(" jmp exit_asm2;"
"string2:"
" .asciz \"'This is the Test_Function().'\\n\";"
"exit_asm2:"
" nop;");
/* This function is just a test function. */
printf("\nA test function to check that the strings are in the data section.\n");
return;
}
int main(void)
{
/* The comment will be inside the function code, all other strings will be in the data section. */
asm(" jmp exit_asm3;"
"string3:"
" .asciz \"'This I never expected, comments inside the code section!'\\n\";"
"exit_asm3:"
" nop;");
/* Note: Private_String() does absolutely NOTHING. */
Private_String();
Test_Function();
printf("\nThese strings should be in the data section.\n");
printf("The hidden string is inside the code section.\n");
printf("'$VER (C)_Barry_Walker_CC0_Licence_[PD].'\n\n");
return 0;
}
/* ***************************************************************************
00000d80 55 48 89 e5 e9 2c 00 00 00 27 24 56 45 52 20 28 |UH...,...'$VER (|
00000d90 43 29 5f 42 61 72 72 79 5f 57 61 6c 6b 65 72 5f |C)_Barry_Walker_|
00000da0 43 43 30 5f 4c 69 63 65 6e 63 65 5f 5b 50 44 5d |CC0_Licence_[PD]|
00000db0 2e 27 0a 00 00 90 5d c3 0f 1f 84 00 00 00 00 00 |.'....].........|
00000dc0 55 48 89 e5 48 83 ec 10 e9 20 00 00 00 27 54 68 |UH..H.... ...'Th|
00000dd0 69 73 20 69 73 20 74 68 65 20 54 65 73 74 5f 46 |is is the Test_F|
00000de0 75 6e 63 74 69 6f 6e 28 29 2e 27 0a 00 90 48 8d |unction().'...H.|
00000df0 3d d5 00 00 00 b0 00 e8 ac 00 00 00 89 45 fc 48 |=............E.H|
00000e00 83 c4 10 5d c3 66 66 2e 0f 1f 84 00 00 00 00 00 |...].ff.........|
00000e10 55 48 89 e5 48 83 ec 10 c7 45 fc 00 00 00 00 e9 |UH..H....E......|
00000e20 3c 00 00 00 27 54 68 69 73 20 49 20 6e 65 76 65 |<...'This I neve|
00000e30 72 20 65 78 70 65 63 74 65 64 2c 20 63 6f 6d 6d |r expected, comm|
00000e40 65 6e 74 73 20 69 6e 73 69 64 65 20 74 68 65 20 |ents inside the |
00000e50 63 6f 64 65 20 73 65 63 74 69 6f 6e 21 27 0a 00 |code section!'..|
00000e60 90 e8 1a ff ff ff e8 55 ff ff ff 48 8d 3d 9d 00 |.......U...H.=..|
00000e70 00 00 b0 00 e8 2f 00 00 00 48 8d 3d be 00 00 00 |...../...H.=....|
00000e80 89 45 f8 b0 00 e8 1e 00 00 00 48 8d 3d dc 00 00 |.E........H.=...|
00000e90 00 89 45 f4 b0 00 e8 0d 00 00 00 31 c9 89 45 f0 |..E........1..E.|
00000ea0 89 c8 48 83 c4 10 5d c3 ff 25 62 01 00 00 00 00 |..H...]..%b.....|
00000eb0 4c 8d 1d 51 01 00 00 41 53 ff 25 41 01 00 00 90 |L..Q...AS.%A....|
00000ec0 68 00 00 00 00 e9 e6 ff ff ff 0a 41 20 74 65 73 |h..........A tes|
00000ed0 74 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 63 68 |t function to ch|
00000ee0 65 63 6b 20 74 68 61 74 20 74 68 65 20 73 74 72 |eck that the str|
00000ef0 69 6e 67 73 20 61 72 65 20 69 6e 20 74 68 65 20 |ings are in the |
00000f00 64 61 74 61 20 73 65 63 74 69 6f 6e 2e 0a 00 0a |data section....|
00000f10 54 68 65 73 65 20 73 74 72 69 6e 67 73 20 73 68 |These strings sh|
00000f20 6f 75 6c 64 20 62 65 20 69 6e 20 74 68 65 20 64 |ould be in the d|
00000f30 61 74 61 20 73 65 63 74 69 6f 6e 2e 0a 00 54 68 |ata section...Th|
00000f40 65 20 68 69 64 64 65 6e 20 73 74 72 69 6e 67 20 |e hidden string |
00000f50 69 73 20 69 6e 73 69 64 65 20 74 68 65 20 63 6f |is inside the co|
00000f60 64 65 20 73 65 63 74 69 6f 6e 2e 0a 00 27 24 56 |de section...'$V|
00000f70 45 52 20 28 43 29 5f 42 61 72 72 79 5f 57 61 6c |ER (C)_Barry_Wal|
00000f80 6b 65 72 5f 43 43 30 5f 4c 69 63 65 6e 63 65 5f |ker_CC0_Licence_|
00000f90 5b 50 44 5d 2e 27 0a 0a 00 00 00 00 01 00 00 00 |[PD].'..........|
*************************************************************************** */
Last login: Thu Feb 21 13:38:22 on ttys000
AMIGA:amiga~> cd Desktop/Code/C
AMIGA:amiga~/Desktop/Code/C> gcc embed_asm.c
AMIGA:amiga~/Desktop/Code/C> ./a.out
A test function to check that the strings are in the data section.
These strings should be in the data section.
The hidden string is inside the code section.
'$VER (C)_Barry_Walker_CC0_Licence_[PD].'
AMIGA:amiga~/Desktop/Code/C> _
I consider this finalised now...
1 Like