[Bug 48594] AnyDesk crashes directly on startup (low WORD of instance handle must be ignored when looking up window classes)

WineHQ Bugzilla wine-bugs at winehq.org
Sat Feb 15 08:11:13 CST 2020


https://bugs.winehq.org/show_bug.cgi?id=48594

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net
                URL|https://anydesk.com/de/down |https://web.archive.org/web
                   |loads/windows               |/20200215095019/https://dow
                   |                            |nload.anydesk.com/AnyDesk.e
                   |                            |xe
            Summary|AnyDesk crashes directly on |AnyDesk crashes directly on
                   |startup                     |startup (low WORD of
                   |                            |instance handle must be
                   |                            |ignored when looking up
                   |                            |window classes)
          Component|-unknown                    |wineserver
           Keywords|                            |download, obfuscation

--- Comment #3 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming.

Relevant part of trace log:

--- snip ---
$ WINEDEBUG=+seh,+relay,+win,+msg,+class,+server wine ./AnyDesk.exe >>log.txt
2>&1
...
0009:Call user32.RegisterClassExW(0031b510) ret=00712cdf
0009:trace:class:CLASS_RegisterClass name=L"ad_win#2\n" hinst=0x405000
style=0x0 clExtr=0x0 winExtr=0x0
0009: create_class( local=1, atom=0000, style=00000000, instance=00405000,
extra=0, win_extra=0, client_ptr=016d9710, name_offset=0, name=L"ad_win#2\n" ) 
...
0009: create_class() = 0 { atom=c050 }
0009:trace:class:RegisterClassExW name=L"ad_win#2\n" atom=c050
wndproc=0x24a0000 hinst=0x405000 bg=(nil) style=00000000 clsExt=0 winExt=0
class=0x16d9710
0009:trace:win:alloc_winproc allocated 0xffff0027 for W 0x24a0000 (40/4096
used)
0009:Ret  user32.RegisterClassExW() retval=0000c050 ret=00712cdf 
...
0009:Call user32.CreateWindowExW(00040000,0232db78 L"ad_win#2\n",02732390
L"AnyDesk",120f0000,000000f0,00000087,000005a0,0000032a,00000000,00000000,00400000,00000000)
ret=00714e5f
0009:trace:win:WIN_CreateWindowEx L"AnyDesk" L"ad_win#2\n" ex=00040000
style=120f0000 240,135 1440x810 parent=(nil) menu=(nil) inst=0x400000
params=(nil)
0009:trace:win:dump_window_styles style: WS_VISIBLE WS_CLIPCHILDREN WS_SYSMENU
WS_THICKFRAME WS_MINIMIZEBOX WS_MAXIMIZEBOX
0009:trace:win:dump_window_styles exstyle: WS_EX_APPWINDOW
0009: create_window( parent=00010020, owner=00000000, atom=0000,
instance=00400000, dpi=96, awareness=2, class=L"ad_win#2\n" )
0009: create_window() = INVALID_HANDLE { handle=00000000, parent=00000000,
owner=00000000, extra=0, class_ptr=00000000, dpi=0, awareness=0 }
0009:warn:win:create_window_handle error 6 creating window
0009:trace:class:GetClassInfoExW (nil) L"ad_win#2\n" 0x31b1d0
0009:trace:class:CLASS_FindClass L"ad_win#2\n" 0x7e800000 -> not found
0009:Ret  user32.CreateWindowExW() retval=00000000 ret=00714e5f
0009:Call KERNEL32.GetLastError() ret=00714e67
0009:Ret  KERNEL32.GetLastError() retval=00000583 ret=00714e67 
...
0009:Call KERNEL32.RaiseException(00002329,00000000,00000000,00000000)
ret=00753fef
0009:trace:seh:raise_exception code=2329 flags=0 addr=0x7b00dae1 ip=7b00dae1
tid=0009
0009:trace:seh:raise_exception  eax=0031ab14 ebx=00cb0620 ecx=00000000
edx=00002329 esi=00000000 edi=0031ab80
0009:trace:seh:raise_exception  ebp=0031ab68 esp=0031ab14 cs=310023 ds=31002b
es=31002b fs=f7ca0063 gs=31006b flags=00200246
0009:trace:seh:call_stack_handlers calling handler at 0x85fd58 code=2329
flags=0
0009:trace:seh:call_stack_handlers handler at 0x85fd58 returned 1
0009:trace:seh:call_stack_handlers calling handler at 0x86bbb8 code=2329
flags=0 
...
--- snip ---

The executable has a stub loader which unpacks the real executable into
'.itext' section which is mapped at 0x404000, see following address space
mappings:

--- snip ---
Address  Size     Info        Content                    Type Protection
...
00400000 00001000 anydesk.exe                            IMG  -R---     
00401000 00003000  ".text"    Executable code            IMG  ER---     
00404000 0090F000  ".itext"                              IMG  -RWC-     
00D13000 00001000  ".rdata"   Read-only initialized data IMG  -R---     
00D14000 002F9000  ".data"    Initialized data           IMG  -RWC-     
0100D000 00004000  ".rsrc"    Resources                  IMG  -R---     
01011000 00001000  ".reloc"   Base relocations           IMG  -R---     
...
--- snip ---

The "real" executable starts at 0x00405000:

--- snip ---
00405000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ..........ÿÿ..
00405010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ¸....... at .......
00405020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00405030 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 ................
00405040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..º..´.Í!¸.LÍ!Th
00405050 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
00405060 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS 
00405070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
00405080 B7 DE F3 62 F3 BF 9D 31 F3 BF 9D 31 F3 BF 9D 31 ·Þóbó¿.1ó¿.1ó¿.1
00405090 60 F1 05 31 F2 BF 9D 31 9C C9 03 31 C9 BF 9D 31 `ñ.1ò¿.1.É.1É¿.1
004050A0 9C C9 37 31 35 BF 9D 31 9C C9 36 31 B6 BF 9D 31 .É715¿.1.É61¶¿.1
004050B0 FA C7 1E 31 FF BF 9D 31 FA C7 19 31 F1 BF 9D 31 úÇ.1ÿ¿.1úÇ.1ñ¿.1
004050C0 FA C7 0E 31 D6 BF 9D 31 F3 BF 9C 31 7C BD 9D 31 úÇ.1Ö¿.1ó¿.1|½.1
004050D0 F3 BF 9D 31 CC BF 9D 31 9C C9 32 31 3D BB 9D 31 ó¿.1Ì¿.1.É21=».1
004050E0 9C C9 06 31 F2 BF 9D 31 9C C9 00 31 F2 BF 9D 31 .É.1ò¿.1.É.1ò¿.1
004050F0 52 69 63 68 F3 BF 9D 31 00 00 00 00 00 00 00 00 Richó¿.1........
00405100 50 45 00 00 4C 01 05 00 6A 24 F9 5D 00 00 00 00 PE..L...j$ù]....
--- snip ---

The app registers several windows classes with instance handle = 0x405000 (the
"real" executable). Later, the app tries to create the user interface / windows
by using instance handle = 0x400000 (the stub one). Wine doesn't handle this
case.

Wine source:

https://source.winehq.org/git/wine.git/blob/7332de64a5a204cc285bdc1f8768d3217103b7dd:/server/window.c#l448

--- snip ---
 448 /* create a new window structure (note: the window is not linked in the
window tree) */
 449 static struct window *create_window( struct window *parent, struct window
*owner,
 450                                      atom_t atom, mod_handle_t instance )
 451 {
 452     int extra_bytes;
 453     struct window *win = NULL;
 454     struct desktop *desktop;
 455     struct window_class *class;
 456 
 457     if (!(desktop = get_thread_desktop( current, DESKTOP_CREATEWINDOW )))
return NULL;
 458 
 459     if (!(class = grab_class( current->process, atom, instance,
&extra_bytes )))
 460     {
 461         release_object( desktop );
 462         return NULL;
 463     }
...
--- snip ---

https://source.winehq.org/git/wine.git/blob/7332de64a5a204cc285bdc1f8768d3217103b7dd:/server/class.c#l110

--- snip ---
 110 struct window_class *grab_class( struct process *process, atom_t atom,
 111                                  mod_handle_t instance, int *extra_bytes )
 112 {
 113     struct window_class *class = find_class( process, atom, instance );
 114     if (class)
 115     {
 116         class->count++;
 117         *extra_bytes = class->win_extra;
 118     }
 119     else set_error( STATUS_INVALID_HANDLE );
 120     return class;
 121 }
--- snip ---

https://source.winehq.org/git/wine.git/blob/7332de64a5a204cc285bdc1f8768d3217103b7dd:/server/class.c#l97

--- snip ---
  97 static struct window_class *find_class( struct process *process, atom_t
atom, mod_handle_t instance )
  98 {
  99     struct list *ptr;
 100 
 101     LIST_FOR_EACH( ptr, &process->classes )
 102     {
 103         struct window_class *class = LIST_ENTRY( ptr, struct window_class,
entry );
 104         if (class->atom != atom) continue;
 105         if (!instance || !class->local || class->instance == instance)
return class;
 106     }
 107     return NULL;
 108 }
--- snip ---

It seems the lower part (WORD) of instance handle is ignored when looking up
window classes.

With this problem fixed, the app starts successfully and shows the user
interface. I've started two instances and could connect locally using the
generated address, simulating remote server and client. 

Malware scans:

https://www.virustotal.com/gui/file/b9ad79eaf7a4133f95f24c3b9d976c72f34264dc5c99030f0e57992cb5621f78/detection

https://www.joesandbox.com/analysis/73420/0/html#overview

Personally I find these remote admin apps (AnyDesk, TeamViewer, ...) highly
questionable as they provide more attack surface. They are also popular bundles
in actual malware ;-)

https://blog.trendmicro.com/trendlabs-security-intelligence/legitimate-application-anydesk-bundled-with-new-ransomware-variant/

$ sha1sum AnyDesk.exe 
df6abbfd20e731689f3c7d2a55f45ac83fbbc40b  AnyDesk.exe

$ du -sh AnyDesk.exe 
3.1M    AnyDesk.exe

$ wine --version
wine-5.1-391-g7332de64a5

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list