Merge pull request #119 from xexyl/2001-anonymous
This commit is contained in:
5 files changed
+161
-103
No files matched your search
@@ -190,12 +190,12 @@ all: data ${TARGET}
|
|||||||
supernova deep_magic magic charon pluto
|
supernova deep_magic magic charon pluto
|
||||||
|
|
||||||
${PROG}: ${PROG}.c
|
${PROG}: ${PROG}.c
|
||||||
|
@echo "NOTE: this entry seems to no longer work."
|
||||||
magic='${CC} ${CFLAGS}'; \
|
magic='${CC} ${CFLAGS}'; \
|
||||||
X='-DA(X)=#X'; \
|
X='-DA(X)=#X'; \
|
||||||
warning='-Dprocessor'; \
|
warning='-Dprocessor'; \
|
||||||
$$magic $$warning -Dmagic= $$X "-DX=A($$magic \"$$X\")" \
|
$$magic $$warning -Dmagic= $$X "-DX=A($$magic \"$$X\")" \
|
||||||
$< -o $@ ${LIBS}
|
$< -o $@ ${LIBS}
|
||||||
anonymous.c
|
|
||||||
|
|
||||||
# alternative executable
|
# alternative executable
|
||||||
#
|
#
|
||||||
|
|||||||
+111
-96
@@ -9,136 +9,151 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
### To run:
|
## To run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./anonymous file
|
./anonymous program
|
||||||
```
|
```
|
||||||
|
|
||||||
### Try:
|
NOTE: this entry seems to no longer work. [Cody Boone
|
||||||
|
Ferguson](/winners.html#Cody_Boone_Ferguson) has offered some tips in the
|
||||||
|
[bugs.md](/bugs.md) file for anyone who mights want to try and fix this but it
|
||||||
|
seems to require a lot of parsing, debugging, an x86 system and possibly knowing
|
||||||
|
the internals of the ELF format (x86 specific). You need to run the program on a
|
||||||
|
binary to test. See the try section below for a program that, if you get the
|
||||||
|
entry to work, would be okay to test it on. Thank you and we will happily credit
|
||||||
|
you if you fix this.
|
||||||
|
|
||||||
|
WARNING: if you do get this to work it will destroy files that it is used on.
|
||||||
|
See the author's warning on this.
|
||||||
|
|
||||||
|
|
||||||
|
## Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./anonymous anonymous.ten.c
|
make anonymous.ten
|
||||||
|
./anonymous anonymous.ten
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' comments:
|
## Judges' comments:
|
||||||
|
|
||||||
Is emulation the sincerest form of flattery? This small program does
|
Is emulation the sincerest form of flattery? This small program does
|
||||||
quite a lot of bit twiddling.
|
quite a lot of bit twiddling.
|
||||||
|
|
||||||
## Author's comments:
|
## Author's comments:
|
||||||
|
|
||||||
This program is an optimizing dynamic binary translator, allowing you to
|
This program is an optimizing dynamic binary translator, allowing you to
|
||||||
run x86 programs on any machine (x86 or otherwise).
|
run x86 programs on any machine (x86 or otherwise).
|
||||||
|
|
||||||
I have included a simple "10 green bottles" program, already compiled
|
I have included a simple "10 green bottles" program, already compiled
|
||||||
for the x86. The program 'ten', and its source (dull) are given as info
|
for the x86. The program 'ten', and its source (dull) are given as info
|
||||||
files. Warning: note that the translator screws around with the binary
|
files. Warning: note that the translator screws around with the binary
|
||||||
you run on it, *will* corrupt the binary to some extent, and may leave
|
you run on it, *will* corrupt the binary to some extent, and may leave
|
||||||
any program you run on it unusable.
|
any program you run on it unusable.
|
||||||
|
|
||||||
The build script should give an example command to run.
|
The build script should give an example command to run.
|
||||||
|
|
||||||
Features
|
### Features
|
||||||
|
|
||||||
Basic Block Cache: Rather than translating each instruction individually
|
Basic Block Cache: Rather than translating each instruction individually
|
||||||
the dynamic binary translator generates a translation for an entire
|
the dynamic binary translator generates a translation for an entire
|
||||||
basic block of subject code. Having translated a block once, the target
|
basic block of subject code. Having translated a block once, the target
|
||||||
code generated will be stored for the duration that the program is
|
code generated will be stored for the duration that the program is
|
||||||
running, so as a program runs its performance will improve, as it hits
|
running, so as a program runs its performance will improve, as it hits
|
||||||
cached blocks. This can be clearly observed in the example program,
|
cached blocks. This can be clearly observed in the example program,
|
||||||
'ten'.
|
'ten'.
|
||||||
|
|
||||||
Target Library Linking:
|
### Target Library Linking:
|
||||||
|
|
||||||
The program runs dynamically linked elf binaries, and when the subject
|
The program runs dynamically linked elf binaries, and when the subject
|
||||||
program attempts to make a call to a standard library, the translator
|
program attempts to make a call to a standard library, the translator
|
||||||
attempts to make an appropriate call to the native system libraries on
|
attempts to make an appropriate call to the native system libraries on
|
||||||
the target machine. This involves mangling between different calling
|
the target machine. This involves mangling between different calling
|
||||||
conventions, etc.
|
conventions, etc.
|
||||||
|
|
||||||
Automatic Endian Detection/Reversal:
|
### Automatic Endian Detection/Reversal:
|
||||||
|
|
||||||
There are various problems raised when attempting to run little endian
|
There are various problems raised when attempting to run little endian
|
||||||
x86 code on a big endian chip, such as a PPC. These problems are dealt
|
x86 code on a big endian chip, such as a PPC. These problems are dealt
|
||||||
with in a manner that is entirely transparent to the user.
|
with in a manner that is entirely transparent to the user.
|
||||||
|
|
||||||
Configuration
|
### Configuration:
|
||||||
|
|
||||||
Warnings:
|
#### Warnings:
|
||||||
|
|
||||||
By default the build script should compile the program with a set of
|
By default the build script should compile the program with a set of
|
||||||
switches such that while compiling the program it generates one error
|
switches such that while compiling the program it generates one error
|
||||||
(which I feel is useful advice). The program should generate no further
|
(which I feel is useful advice). The program should generate no further
|
||||||
compiler errors while it is running (yes, the program can generate
|
compiler errors while it is running (yes, the program can generate
|
||||||
compiler errors while it is running). If you do not wish to see this
|
compiler errors while it is running). If you do not wish to see this
|
||||||
error, or if the program generates any further error when compiled using
|
error, or if the program generates any further error when compiled using
|
||||||
your C compiler please remove the "warning=..." line from the build
|
your C compiler please remove the "warning=..." line from the build
|
||||||
script.
|
script.
|
||||||
|
|
||||||
Optimization:
|
### Optimization:
|
||||||
|
|
||||||
The build script contains a "-O1" switch for the compiler. Increasing
|
The build script contains a "-O1" switch for the compiler. Increasing
|
||||||
the optimization level will make the program run *slower*, while
|
the optimization level will make the program run *slower*, while
|
||||||
compiling the program without any optimization will allow it to run
|
compiling the program without any optimization will allow it to run
|
||||||
*faster*.
|
*faster*.
|
||||||
|
|
||||||
Obfuscation
|
### Obfuscation:
|
||||||
|
|
||||||
The most obvious part of the obfuscation is probably the mess of defines
|
The most obvious part of the obfuscation is probably the mess of defines
|
||||||
at the top. This may seem a somewhat tired old obfuscation - however
|
at the top. This may seem a somewhat tired old obfuscation - however
|
||||||
since many of these macros are (sometimes only) used by the program once
|
since many of these macros are (sometimes only) used by the program once
|
||||||
it has dynamically recompiled itself, they are only referenced within
|
it has dynamically recompiled itself, they are only referenced within
|
||||||
the source code from within strings - and therefore the macros cannot be
|
the source code from within strings - and therefore the macros cannot be
|
||||||
expanded. Furthermore, some of these strings of code are not given as
|
expanded. Furthermore, some of these strings of code are not given as
|
||||||
strings, but instead are wrapped up in macros that use the "#"
|
strings, but instead are wrapped up in macros that use the "#"
|
||||||
preprocessor operator to turn them into strings. In the hope throwing a
|
preprocessor operator to turn them into strings. In the hope throwing a
|
||||||
few C beautifiers the macro to generate the strings is not contained
|
few C beautifiers the macro to generate the strings is not contained
|
||||||
within the source code but instead is passed in on the command line.
|
within the source code but instead is passed in on the command line.
|
||||||
|
|
||||||
Buried under all this, and the fact that the entire program is just a
|
Buried under all this, and the fact that the entire program is just a
|
||||||
call to exit, there are some nice subtle little obfuscations. For
|
call to exit, there are some nice subtle little obfuscations. For
|
||||||
example, you may notice that there are a couple of macros that use the
|
example, you may notice that there are a couple of macros that use the
|
||||||
"##" preprocessor operator to build pairs of functions. One of these
|
"##" preprocessor operator to build pairs of functions. One of these
|
||||||
macros is used to build to pairs of functions of which only one has
|
macros is used to build to pairs of functions of which only one has
|
||||||
local variables which shadow global variables; so one modifies the
|
local variables which shadow global variables; so one modifies the
|
||||||
global state, and the other doesn't.
|
global state, and the other doesn't.
|
||||||
|
|
||||||
There is also quite a nice trick where I wave a magic wand, and a chunk
|
There is also quite a nice trick where I wave a magic wand, and a chunk
|
||||||
of code which should only be run when the program is run for the first
|
of code which should only be run when the program is run for the first
|
||||||
time (setting the PC to point at main, etc) gets turned into a
|
time (setting the PC to point at main, etc) gets turned into a
|
||||||
frog^M^M^M^Mstring. The C compiler sees a string by itself in the code,
|
frog^M^M^M^Mstring. The C compiler sees a string by itself in the code,
|
||||||
thinks "yup, thats a valid C expression", and quietly moves on to the
|
thinks "yup, that's a valid C expression", and quietly moves on to the
|
||||||
next line of code.
|
next line of code.
|
||||||
|
|
||||||
Limitations
|
### Limitations:
|
||||||
|
|
||||||
Due to space limitations only a handful of instructions are supported,
|
Due to space limitations only a handful of instructions are supported,
|
||||||
those instructions which are supported may supported in somewhat
|
those instructions which are supported may supported in somewhat
|
||||||
non-conventional ways, chunks of the architecture (e.g. flags) are just
|
non-conventional ways, chunks of the architecture (e.g. flags) are just
|
||||||
ignored, the elf loader does not really load the elf binary, the target
|
ignored, the elf loader does not really load the elf binary, the target
|
||||||
library linking can only pass up to 3 parameters to the target library
|
library linking can only pass up to 3 parameters to the target library
|
||||||
function, etc, etc, etc.
|
function, etc, etc, etc.
|
||||||
|
|
||||||
In short, please consider this a full disclaimer for any bug that may
|
In short, please consider this a full disclaimer for any bug that may
|
||||||
turn up - yes the program is unsafe, but it's pretty cool anyway.
|
turn up - yes the program is unsafe, but it's pretty cool anyway.
|
||||||
|
|
||||||
Despite all this, the translator is not exclusively limited to running
|
Despite all this, the translator is not exclusively limited to running
|
||||||
the 'ten' program. Other trivial x86 programs may run on the translator
|
the 'ten' program. Other trivial x86 programs may run on the translator
|
||||||
- and I have successfully run a wide range of HelloWorld programs,
|
\- and I have successfully run a wide range of HelloWorld programs,
|
||||||
including one of last years IOCCC winners, 'tomx'.
|
including one of last years IOCCC winners, 'tomx'.
|
||||||
|
|
||||||
Complete Program
|
### Complete Program:
|
||||||
|
|
||||||
The fact that the program makes calls to system and execv may imply that
|
The fact that the program makes calls to system and execv may imply that
|
||||||
it is not a complete program in its own right, as it relies on other
|
it is not a complete program in its own right, as it relies on other
|
||||||
programs. The call to system is a call to ask gcc to recompile the
|
programs. The call to system is a call to ask gcc to recompile the
|
||||||
translator with a new set of switches, and the call to execv asks for
|
translator with a new set of switches, and the call to execv asks for
|
||||||
the newly compiled program to be executed. I would point out that
|
the newly compiled program to be executed. I would point out that
|
||||||
almost every other entry to this competition also require a C compiler
|
almost every other entry to this competition also require a C compiler
|
||||||
(well, the published winners at any rate, and I recognize that a few
|
(well, the published winners at any rate, and I recognize that a few
|
||||||
don't). There is little real difference between this program and one
|
don't). There is little real difference between this program and one
|
||||||
like last years entry 'dhyang'; both are just C programs that generate C
|
like last years entry 'dhyang'; both are just C programs that generate C
|
||||||
code as their output.
|
code as their output.
|
||||||
|
|
||||||
Enjoy, thanks!
|
Enjoy, thanks!
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
#define l int*
|
#define l int*
|
||||||
#define F char
|
#define F char
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ int main() {
|
|||||||
while(bottles) {
|
while(bottles) {
|
||||||
sing(bottles);
|
sing(bottles);
|
||||||
sing(bottles);
|
sing(bottles);
|
||||||
printf("And if one green bottle should accidently fall,\nThere'd be ");
|
printf("And if one green bottle should accidentally fall,\nThere'd be ");
|
||||||
sing(--bottles);
|
sing(--bottles);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,46 @@ related to making it work under macOS as all that did was removing some invalid
|
|||||||
prototypes and use `printf()` instead of the invalid pointer to it (incompatible
|
prototypes and use `printf()` instead of the invalid pointer to it (incompatible
|
||||||
type).
|
type).
|
||||||
|
|
||||||
|
### [2001/anonymous](2001/anonymous/anonymous.c) ([README.md](2001/anonymous/README.md))
|
||||||
|
|
||||||
|
This entry seems to no longer work and we would appreciate any help from anyone
|
||||||
|
who can fix this. [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) has
|
||||||
|
the following hints that might help but he has no system where he could test
|
||||||
|
it. [Yusuke Endoh](/winners.html#Yusuke_Endoh) [wrote a little bit about
|
||||||
|
it](https://mame-github-io.translate.goog/ioccc-ja-spoilers/2001/anonymous.html?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-US&_x_tr_pto=wapp) that
|
||||||
|
might or might not help but he too could not get it to work.
|
||||||
|
|
||||||
|
Tips from Cody:
|
||||||
|
|
||||||
|
- Try a beautifier on the original C code.
|
||||||
|
- Use cpp to make the functions easier to parse. For instance if you're in the
|
||||||
|
directory try `cpp -E anonymous.cp > anonymous.cpp` and look at that file to see
|
||||||
|
the functions. It might or might not be helpful to use cpp on the beautified
|
||||||
|
source.
|
||||||
|
- After beautifying it try changing references of the macros (where not too
|
||||||
|
complicated) to their definitions. For instance in vim you might do:
|
||||||
|
`:%s/\<l\>/int */g` and then delete the line that was changed to `#define int *
|
||||||
|
int*` (or else do a range substitute so it's not changed). You might not need
|
||||||
|
this if you use the cpp. This might be useful anyway to more easily test things.
|
||||||
|
- If your system has a `setarch` tool that might or might not be of help (I'm
|
||||||
|
not too familiar with its internals).
|
||||||
|
- The code appears to do everything from one call to `exit(3)` but it makes use
|
||||||
|
of the ternary operator and possibly the comma operator.
|
||||||
|
- Check the Makefile for the defines but also observe that those are in the
|
||||||
|
source file. It appears that the entry might try compiling as well but that's
|
||||||
|
from a quick glance.
|
||||||
|
- The original main() started like: `main (char *ck, char **k)` but we made it
|
||||||
|
compilable for clang by changing it to be: `main (int cka, char **k) { char *ck
|
||||||
|
= (char *)cka;` which might or might not be good.
|
||||||
|
- The author warns that only simple source (once compiled) would work so make
|
||||||
|
use of the provided source file
|
||||||
|
[2001/anonymous/anonymous.ten.c](2001/anonymous/anonymous.ten.c). To compile try
|
||||||
|
`make anonymous.ten` from the entry directory which you can then run the entry
|
||||||
|
on. Note that it needs to be compiled as a x86 program.
|
||||||
|
- The program will to an extent destroy files it is used on. See the author's
|
||||||
|
warning in their comments on that.
|
||||||
|
|
||||||
|
|
||||||
### [2004/burley](2004/burley/burley.c) ([README.md](2004/burley/README.md))
|
### [2004/burley](2004/burley/burley.c) ([README.md](2004/burley/README.md))
|
||||||
|
|
||||||
This entry did not compile with clang but [Cody Boone
|
This entry did not compile with clang but [Cody Boone
|
||||||
@@ -52,11 +92,12 @@ experience with `longjmp`). In particular:
|
|||||||
> The longjmp() routines may not be called after the routine which called the
|
> The longjmp() routines may not be called after the routine which called the
|
||||||
> setjmp() routines returns.
|
> setjmp() routines returns.
|
||||||
3. The main() originally returned a call to main() which appeared to be an
|
3. The main() originally returned a call to main() which appeared to be an
|
||||||
infinite recursion at least as it was; now it returns a call to poke() which has the same number
|
infinite recursion at least as it was; now it returns a call to poke() which has
|
||||||
and type of args (1, `char *`) that main() had. This appears to not be an
|
the same number and type of args (1, `char *`) that main() had. This appears to
|
||||||
infinite recursion but I might be reading it wrong. Perhaps that is the problem?
|
not be an infinite recursion but I might be reading it wrong. Changing it to not
|
||||||
4. As well main() had only one arg, a `char *`, and there were (seemingly)
|
return itself and the same problem occurs so perhaps this is not the problem.
|
||||||
needless casts to `char *` from gets().
|
4. As well main() had only one arg, a `char *`, and there was a (seemingly)
|
||||||
|
needless cast to `char *` from gets(). This cast remains in the code however.
|
||||||
5. The code no longer uses `gets()` but `fgets()`; this is not the problem
|
5. The code no longer uses `gets()` but `fgets()`; this is not the problem
|
||||||
however.
|
however.
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user