Page 1 of 1

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

Posted: Wed Jul 26, 2017 4:50 pm
by Vlad
Динамическая библиотека после протекции 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
- Пробовали протектить как и платной версией, так и последним вышедшим демо
- Пробовали протектить без протекции функций вовсе(просто обычной прогон либы через протектор)

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

Posted: Thu Jul 27, 2017 7:11 am
by Admin
Попробуйте в опциях отключить упаковку.

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

Posted: Thu Jul 27, 2017 9:06 am
by Vlad
Уже пытались, это так себе вариант по той причине, что в незапакованном бинарен видно литералы(ключи, данные для шифрования и т.д.)

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

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

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

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

Posted: Thu Jul 27, 2017 11:14 am
by Vlad
Размер файла после сжатия: 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

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

Posted: Thu Jul 27, 2017 11:38 am
by Vlad
Сегменты загрузки библиотеки без сжатия:

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

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

Posted: Thu Jul 27, 2017 12:16 pm
by Admin
Я правильно понимаю, что на 10.13 проблем нет, а есть только на 10.12?

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

Posted: Thu Jul 27, 2017 12:38 pm
by Vlad
Библиотека одна. Она не меняется, соответственно подобные ошибки в загрузочных командах присутствуют везде. Однако, только на 10.12(может зависит не от системы, а от других факторов) эта проблема приводит к невалидной загрузки библиотеки. Может другие системы эту ошибку как то разруливают самостоятельно, пока неизвестно.
Ошибка на 10.12:

Code: Select all

 malformed mach-o image: segment __TEXT has vmsize != filesize and is executable

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

Posted: Fri Jul 28, 2017 6:55 am
by Admin
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 сегменты.

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

Posted: Mon Sep 11, 2017 7:28 am
by Admin
У вас эта библиотека подписана сертификатом? Я пока не могу понять при каких условиях OSX начинает валидировать информацию о сегментах.

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

Posted: Fri Sep 29, 2017 2:08 pm
by Vlad
Нет, не подписана.
Попробуйте воспроизвести на 10.12 Sierra.

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

Posted: Sat Sep 30, 2017 10:44 am
by Admin
Дак и так пробуем на 10.12 - не воспроизводится.

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

Posted: Mon Nov 13, 2017 3:01 pm
by Admin
Вобщем разобрались - начиная с Sierra (10.12) есть 2 случая когда включается расширенная проверка библиотек:
1. У основного бинарника указана минимальная версия SDK - 10.12
2. Основной бинарник подписан с опцией валидации библиотек