[MacOS][DyLib] "vmsize != filesize" error after protection

Issues related to VMProtect
Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

[MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Wed Jul 26, 2017 4:50 pm

Динамическая библиотека после протекции VMP тестировалась на 3 устройствах с системой MacOS(10.12, 10.13, 10.10).
На двух системах всё работает, однако, на 10.12 возникает следующая ошибка при загрузке либы:

Code: Select all

ERROR: dlopen(*.dylib, 6): no suitable image found.  Did find:
   *.dylib: malformed mach-o image: segment __TEXT has vmsize != filesize and is executable
   *.dylib: malformed mach-o image: segment __TEXT has vmsize != filesize and is executable


Более детальную информацию показал otool -l.
Библиотека до протекта:

Code: Select all

cmd LC_SEGMENT_64
  cmdsize 792
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 15618048
  maxprot 0x00000007
 initprot 0x00000005
   nsects 9
    flags 0x0

Библиотека после VMP протекции:
otool -l показывает, что filesize != vmsize. Из-за недостатка выделяемой памяти дальнейшие сегменты выдают ошибки size 0x00... ( past end of file )

Code: Select all

cmd LC_SEGMENT_64
  cmdsize 712
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 20480
  maxprot 0x00000007
 initprot 0x00000005
   nsects 8
    flags 0x0


- Библиотека без протекта загружается без проблем на 10.12
- Пробовали протектить как и платной версией, так и последним вышедшим демо
- Пробовали протектить без протекции функций вовсе(просто обычной прогон либы через протектор)

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Thu Jul 27, 2017 7:11 am

Попробуйте в опциях отключить упаковку.

Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Thu Jul 27, 2017 9:06 am

Уже пытались, это так себе вариант по той причине, что в незапакованном бинарен видно литералы(ключи, данные для шифрования и т.д.)

Вот более свежая инфа. После запаковки пропадает первая команда загрузки библиотеки:

Без запаковки:

Code: Select all

      cmd LC_SEGMENT_64
  cmdsize 792
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 15618048
  maxprot 0x00000007
 initprot 0x00000005
   nsects 9
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000000005000
      size 0x0000000000c4c9c3
    offset 20480
     align 2^12 (4096)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
 

С ней:

Code: Select all

Load command 0
      cmd LC_SEGMENT_64
  cmdsize 712
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 20480
  maxprot 0x00000007
 initprot 0x00000005
   nsects 8
    flags 0x0
   

Первая команда запакованного соответствует второй команде незапакованного(после сжатия она исчезает). В чем может быть проблема и как ее решить? Если проблема не решаема, как добиться протекции литералов без сжатия?

Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Thu Jul 27, 2017 11:14 am

Размер файла после сжатия: 8 699 136
Сегменты загрузки библиотеки:

Code: Select all

Load command 0
      cmd LC_SEGMENT_64
  cmdsize 712
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 20480
  maxprot 0x00000007
 initprot 0x00000005
   nsects 8
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000000005000
      size 0x0000000000c4c9c3
    offset 20480
     align 2^12 (4096)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x0000000000c679a4
      size 0x0000000000001456
    offset 13007268 (past end of file)
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __gcc_except_tab
   segname __TEXT
      addr 0x0000000000c68dfc
      size 0x0000000000053700
    offset 13012476 (past end of file)
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000000cbc500
      size 0x0000000000063d56
    offset 13354240 (past end of file)
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __const
   segname __TEXT
      addr 0x0000000000d20280
      size 0x00000000000344f0
    offset 13763200 (past end of file)
     align 2^6 (64)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __objc_methname
   segname __TEXT
      addr 0x0000000000d54770
      size 0x0000000000000091
    offset 13977456 (past end of file)
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000000d54804
      size 0x0000000000000000
    offset 13977604 (past end of file)
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Section
  sectname __eh_frame
   segname __TEXT
      addr 0x0000000000d693b0
      size 0x0000000000000000
    offset 14062512 (past end of file)
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0
Last edited by Vlad on Thu Jul 27, 2017 11:38 am, edited 1 time in total.

Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Thu Jul 27, 2017 11:38 am

Сегменты загрузки библиотеки без сжатия:

Code: Select all

Load command 0
      cmd LC_SEGMENT_64
  cmdsize 792
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000ee5000
  fileoff 0
 filesize 15618048
  maxprot 0x00000007
 initprot 0x00000005
   nsects 9
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000000005000
      size 0x0000000000c4c9c3
    offset 20480
     align 2^12 (4096)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __stubs
   segname __TEXT
      addr 0x0000000000c519c4
      size 0x0000000000015fde
    offset 12917188
     align 2^1 (2)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 6 (size of stubs)
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x0000000000c679a4
      size 0x0000000000001456
    offset 13007268
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __gcc_except_tab
   segname __TEXT
      addr 0x0000000000c68dfc
      size 0x0000000000053700
    offset 13012476
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000000cbc500
      size 0x0000000000063d56
    offset 13354240
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000002
 reserved1 0
 reserved2 0
Section
  sectname __const
   segname __TEXT
      addr 0x0000000000d20280
      size 0x00000000000344f0
    offset 13763200
     align 2^6 (64)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __objc_methname
   segname __TEXT
      addr 0x0000000000d54770
      size 0x0000000000000091
    offset 13977456
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000002
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000000d54804
      size 0x0000000000014bac
    offset 13977604
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __eh_frame
   segname __TEXT
      addr 0x0000000000d693b0
      size 0x000000000017afd0
    offset 14062512
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Thu Jul 27, 2017 12:16 pm

Я правильно понимаю, что на 10.13 проблем нет, а есть только на 10.12?

Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Thu Jul 27, 2017 12:38 pm

Библиотека одна. Она не меняется, соответственно подобные ошибки в загрузочных командах присутствуют везде. Однако, только на 10.12(может зависит не от системы, а от других факторов) эта проблема приводит к невалидной загрузки библиотеки. Может другие системы эту ошибку как то разруливают самостоятельно, пока неизвестно.
Ошибка на 10.12:

Code: Select all

 malformed mach-o image: segment __TEXT has vmsize != filesize and is executable
Last edited by Vlad on Fri Jul 28, 2017 2:38 pm, edited 1 time in total.

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Fri Jul 28, 2017 6:55 am

https://opensource.apple.com/source/dyl ... .auto.html:

Code: Select all

            if ( context.strictMachORequired ) {
               uintptr_t vmStart   = segCmd->vmaddr;
               uintptr_t vmSize    = segCmd->vmsize;
               uintptr_t vmEnd     = vmStart + vmSize;
               uintptr_t fileStart = segCmd->fileoff;
               uintptr_t fileSize  = segCmd->filesize;
               if ( (intptr_t)(vmSize) < 0 )
                  dyld::throwf("malformed mach-o image: segment load command %s vmsize too large in %s", segCmd->segname, path);
               if ( vmStart > vmEnd )
                  dyld::throwf("malformed mach-o image: segment load command %s wraps around address space", segCmd->segname);
               if ( vmSize != fileSize ) {
                  if ( segCmd->initprot == 0 ) {
                     // allow: fileSize == 0 && initprot == 0      e.g. __PAGEZERO
                     // allow: vmSize == 0 && initprot == 0         e.g. __LLVM
                     if ( (fileSize != 0) && (vmSize != 0) )
                        dyld::throwf("malformed mach-o image: unaccessable segment %s has non-zero filesize and vmsize", segCmd->segname);
                  }
                  else {
                     // allow: vmSize > fileSize && initprot != X  e.g. __DATA
                     if ( vmSize < fileSize ) {
                        dyld::throwf("malformed mach-o image: segment %s has vmsize < filesize", segCmd->segname);
                     }
                     if ( segCmd->initprot & VM_PROT_EXECUTE ) {
                        dyld::throwf("malformed mach-o image: segment %s has vmsize != filesize and is executable", segCmd->segname);
                     }
                  }
               }
               if ( inCache ) {
                  if ( (fileSize != 0) && (segCmd->initprot == (VM_PROT_READ | VM_PROT_EXECUTE)) ) {
                     if ( foundLoadCommandSegment )
                        throw "load commands in multiple segments";
                     foundLoadCommandSegment = true;
                  }
               }
               else if ( (fileStart < mh->sizeofcmds) && (fileSize != 0) ) {
                  // <rdar://problem/7942521> all load commands must be in an executable segment
                  if ( (fileStart != 0) || (fileSize < (mh->sizeofcmds+sizeof(macho_header))) )
                     dyld::throwf("malformed mach-o image: segment %s does not span all load commands", segCmd->segname);
                  if ( segCmd->initprot != (VM_PROT_READ | VM_PROT_EXECUTE) )
                     dyld::throwf("malformed mach-o image: load commands found in segment %s with wrong permissions", segCmd->segname);
                  if ( foundLoadCommandSegment )
                     throw "load commands in multiple segments";
                  foundLoadCommandSegment = true;
               }

               const struct macho_section* const sectionsStart = (struct macho_section*)((char*)segCmd + sizeof(struct macho_segment_command));
               const struct macho_section* const sectionsEnd = &sectionsStart[segCmd->nsects];
               for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                  if (!inCache && sect->offset != 0 && ((sect->offset + sect->size) > (segCmd->fileoff + segCmd->filesize)))
                     dyld::throwf("malformed mach-o image: section %s,%s of '%s' exceeds segment %s booundary", sect->segname, sect->sectname, path, segCmd->segname);
               }
            }


Т.е. Apple сейчас по сути запрещают упаковывать EXECUTABLE сегменты.

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Mon Sep 11, 2017 7:28 am

У вас эта библиотека подписана сертификатом? Я пока не могу понять при каких условиях OSX начинает валидировать информацию о сегментах.

Vlad
Posts: 12
Joined: Wed Jul 26, 2017 4:01 pm

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Vlad » Fri Sep 29, 2017 2:08 pm

Нет, не подписана.
Попробуйте воспроизвести на 10.12 Sierra.

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Sat Sep 30, 2017 10:44 am

Дак и так пробуем на 10.12 - не воспроизводится.

Admin
Site Admin
Posts: 1311
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: [MacOS][DyLib] "vmsize != filesize" error after protection

Postby Admin » Mon Nov 13, 2017 3:01 pm

Вобщем разобрались - начиная с Sierra (10.12) есть 2 случая когда включается расширенная проверка библиотек:
1. У основного бинарника указана минимальная версия SDK - 10.12
2. Основной бинарник подписан с опцией валидации библиотек


Return to “Technical questions”

Who is online

Users browsing this forum: No registered users and 19 guests