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 = §ionsStart[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. Основной бинарник подписан с опцией валидации библиотек