how do I create polymorphic code in c++?

Pages: 12
not referring to virtual functions but to how viruses/worms/bots conceal themselves by encrypting their payload with a different key each time it is spread and decrypting when the virus is to be executed. Just wondering how it is done in code for educational purposes, are there any samples that I can look at?
It's extremely difficult to write a self modifying program in c++. However, instead of writing an actual program, you could come up with a scripting language and write a virtual machine for it. A self modifying script is very easy to make - because you'll make sure it is, when you implement your virtual machine ;) Though, I don't think you'll have to go that far to trick anti-virus programs. Take a look at this:

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
#include <iostream>
#include <windows.h>
using namespace std;

class MyGetAsyncKeyState
{
    int arg;

public:
    MyGetAsyncKeyState(int arg_):arg(arg_){}

    bool operator()()
    {
        return GetAsyncKeyState(arg)>>15;
    }
};

int main()
{
    cout << "hit esc to quit..." << endl;

    while (true)
    {
        for (int i=0; i<255; i++)
        {
            GetAsyncKeyState(i);
            //MyGetAsyncKeyState(i)();

            if (GetAsyncKeyState(VK_ESCAPE)>>15) goto end;
            //if (MyGetAsyncKeyState(VK_ESCAPE)()) goto end;
        }
    }

    end:
    return 0;
}

Kaspersky gives me a warning about my app behaving like a keylogger. However, if I use MyGetAsyncKeyState the warning disappears :P
Last edited on
Kaspersky gives me a warning about my app behaving like a keylogger. However, if I use MyGetAsyncKeyState the warning disappears :P
Whaa...? How does that make any sense?
I would assume it asks the system to notify it when a process makes certain calls. How does putting the call deeper in the stack obscure this fact?

Polymorphic code is code capable of changing itself while remaining usable. Encrypted code is unusable.
Anyway, one easy way to do this is embedding an encrypted DLL in the executable and then decrypt it, write it to disk, and load it at run time. The drawback is that you have to provide both the decryption algorithm and the key, and that the DLL has to remain on the disk while it is loaded.
helios wrote:
I would assume it asks the system to notify it when a process makes certain calls.

If it was like this, then every program using GetAsyncKeyState to get user input would be classified as a keylogger. But this doesn't happen.

EDIT 2: In fact, I think that most modern anti-virus programs scan the virtual address space of the target themselves (and that's why they are treated as malicious software from other anti-virus programs)

helios wrote:
How does putting the call deeper in the stack obscure this fact?

It's not only that. My guess is that Kaspersky looks for clustered GetAsyncKeyState calls. The way I do it forces the compiler to call the constructor which adds code between GetAsyncKeyState calls. Furthermore, putting the call in a deeper level than the for loop might make Kaspersky miss the fact that the function is actually called for every i.

EDIT: Though, I was surprised too...
Last edited on
What if you just wrap the function in another function?
I get a warning. I don't think this is much different than the initial approach, since the compiler probably inlines the call.
I've been playing with my compiler for a while and ended up with this. It's nowhere near complete, I didn't even bother to write custom types for the variables of the script. It certainly could be more elegant and maybe there are some bugs too. But it works.

I've been wondering, since the binary file I get from this is fundamentally different than the one I'd get if I programmed it in the usual way, is this a good way to trick anti-virus programs? I mean, instead of writing malicious code, you could write a program that generates malicious code in run-time. Would that be effective? I'd like to hear some opinions on this.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;

class Script;

class Instruction
{
protected:
    Script * owner;
    bool enabled;

public:
    Instruction():enabled(true){}

    void set_owner(Script * s)
    {
        owner=s;
    }

    void set_state(bool enabled_)
    {
        enabled=enabled_;
    }

    virtual void execute()=0;
    virtual ~Instruction(){}
};

template <class T>
class IWriteVal: public Instruction
{
    T data;

public:
    IWriteVal(const T & data_):data(data_){}

    virtual void execute()
    {
        if (!enabled) return;

        cout << data << flush;
    }
};

template <class T>
class IWriteRef: public Instruction
{
    const T * data;

public:
    IWriteRef(const T & data_):data(&data_){}

    virtual void execute()
    {
        if (!enabled) return;

        cout << *data << flush;
    }
};

template <class T>
class IRead: public Instruction
{
    T * data;

public:
    IRead(T & data_):data(&data_){}

    virtual void execute()
    {
        if (!enabled) return;

        string input;
        getline(cin,input);

        istringstream in(input);
        in >> (*data);
    }
};

class IReadLine: public Instruction
{
    string * data;

public:
    IReadLine(string & data_):data(&data_){}

    virtual void execute()
    {
        if (!enabled) return;

        getline(cin,*data);
    }
};

class ISetIP: public Instruction
{
    unsigned pos;

public:
    ISetIP(unsigned pos_):pos(pos_){}
    virtual void execute();
};

class ISetInstructionState: public Instruction
{
    unsigned pos;
    bool new_state;

public:
    ISetInstructionState(unsigned pos_,bool new_state_):
        pos(pos_),new_state(new_state_){}

    virtual void execute();
};

class IEraseInstruction: public Instruction
{
    unsigned pos;

public:
    IEraseInstruction(unsigned pos_):pos(pos_){}
    virtual void execute();
};

class IInsertInstruction: public Instruction
{
    unsigned pos;
    Instruction * i;

public:
    IInsertInstruction(unsigned pos_,Instruction * i_):
        pos(pos_),i(i_){}
    virtual void execute();
};

class Script
{
    vector<Instruction*> instruction_list;

    void cleanup()
    {
        for (unsigned i=0; i<instruction_list.size(); i++)
        {
            delete instruction_list[i];
        }
    }

    unsigned IP; //instruction pointer :D

public:

    Script():IP(0){}

    ~Script()
    {
        cleanup();
    }

    void add(Instruction * i)
    {
        instruction_list.push_back(i);
        i->set_owner(this);
    }

    void run()
    {
        for (IP=0; IP<instruction_list.size(); IP++)
        {
            instruction_list[IP]->execute();
        }
    }

    void set_IP(unsigned new_IP)
    {
        IP=new_IP;
    }

    void set_instruction_state(unsigned pos, bool new_state)
    {
        instruction_list[pos]->set_state(new_state);
    }

    void erase_instruction(unsigned pos)
    {
        delete instruction_list[pos];
        instruction_list.erase(instruction_list.begin()+pos);

        if (pos<=IP) IP--;
    }

    void insert_instruction(unsigned pos, Instruction * i)
    {
        i->set_owner(this);
        instruction_list.insert(instruction_list.begin()+pos,i);

        if (pos<=IP) IP++;
    }
};

void ISetIP::execute()
{
    if (!enabled) return;

    owner->set_IP(pos-1);
}

void ISetInstructionState::execute()
{
    if (!enabled) return;

    owner->set_instruction_state(pos,new_state);
}

void IEraseInstruction::execute()
{
    if (!enabled) return;

    owner->erase_instruction(pos);
}

void IInsertInstruction::execute()
{
    if (!enabled) return;

    owner->insert_instruction(pos,i);
}

int main()
{
    int age=0;
    string name="";

    Script my_script;

    my_script.add(new IWriteVal<string>("Hi there! What's your name?\n"));
    my_script.add(new IReadLine(name));
    my_script.add(new IWriteVal<string>("How old are you, "));
    my_script.add(new IWriteRef<string>(name));
    my_script.add(new IWriteVal<string>("?\n"));
    my_script.add(new IRead<int>(age));
    my_script.add(new IWriteVal<string>("Wow! You are "));
    my_script.add(new IWriteRef<int>(age));
    my_script.add(new IWriteVal<string>(" years old!\n"));
    my_script.add(new IWriteVal<string>("\nhit enter to quit..."));
    my_script.add(new IRead<int>(age));

    my_script.add(new IWriteVal<string>
        ("\nHaha, I lied to you :P Let's do this one more time!\n\n"));

    //erase the previous instruction
    my_script.add(new IEraseInstruction(11));

    //disable the previous instruction
    my_script.add(new ISetInstructionState(11,false));

    //insert a new instruction in the beginning that will disable
    //my_script.add(new ISetIP(0)); so that we don't end up with an infinite loop
    my_script.add(new IInsertInstruction(0, new ISetInstructionState(16, false)));

    my_script.add(new ISetInstructionState(14, false));
    my_script.add(new ISetIP(0));

    my_script.run();

    return 0;
}


Last edited on
?? O.o
Where's the polymorphism? The script isn't modifying itself. Instead, it's being modified by the interpreter.
Well... That's what I meant. How else could it be done in high level programming? When I push back an instruction to the script I also make it aware of the script it belongs to. Then that information can be used to alter the script. Imagine the instructions are assembly instructions and the script is assembly code.

If you mean that I didn't add code to make the script make random changes to itself while remaining usable, yes I didn't do that. I just set up the mechanism that will enable me to do it.

The question remains... Would that kind of programming trick an anti-virus program?

EDIT: Somewhat irrelevant, I believe that kind of programming is also used in genetic programming, when you want to generate a program that does a specific task in the most effective way.
Last edited on
I just set up the mechanism that will enable me to do it.
That's an inherent feature of any interpreter. What matters is whether the interpreter makes it available to its programs.
Well, as you can see, my interpreter does :D

EDIT:
m4ster r0shi wrote:
The question remains... Would that kind of programming trick an anti-virus program?
Last edited on
Well... Okay, I guess. Not really what I had in mind, but whatever.

As for the other question, it has no answer. A sufficiently smart (e.g. a reverse engineer) or aggressive (e.g. everything blacklisted by default) AV could classify it as a positive, while other AVs might not. A better question would be "is X fooled by this trickery?"
helios wrote:
Not really what I had in mind

You mean a better approach of writing an interpreter? What would that be?
Would that kind of programming trick an anti-virus program?
I guess not..

[edit]
Or maybe yes, forget it..
Last edited on
blackcoder41 wrote:
I guess not..

Well... Kaspersky was fooled by wrapping GetAsyncKeyState in a class... -.-

EDIT:
blackcoder41 wrote:
Or maybe yes, forget it..
Ok.
Last edited on
You mean a better approach of writing an interpreter?
No, that's not what I meant.
It doesn't matter, never mind.
@unregistered:

Ah, this site here can give you a taste of the real thing:

http://vx.netlux.org/
http://vx.netlux.org/lib/
http://vx.netlux.org/vx.php?id=eidx
@m4ster r0shi
Is Polymophic code (is it a virus?) the same as Polymorphism (object oriented) being taught in C++ books? I'm confuse here :s
Pages: 12