Introduction:
Barry Kauler had released his program "Embedded Vector Editor" version 3.56.
We can download it(eve.exe) in many sites,
even in Barry's backup site https://bkhome.org/archive/goosee/
-------------- 1.symptoms ---------------------------------------------
But this program had 3 bugs at least:
1)How to modify coordinates of points?
After click right_button, we can see lots of coordinates,
and choose 1 of them,
then reInput the value of x or y.
We can NOT move the coordinates by mouse or by left\right\up\down keys.
2)Point's count in Any polyline or any polygon,
must less than 42 (points).
See about gandharva.eve, any curve(more than 42 points) had been cut.
3)Without call StrokeAndFillPath by logBrush in closeFigure,
so no color in displaying tiger.eve.
Bug1 is no solution.
Bug2 can use polyLine.txt to restore some feature of the program(eve.exe),
by commandLine "difc.exe polyline.txt", we can get eve_polyline.exe,
by commandLine "eve_polyline.exe gandharva.eve",we will see normal figure now.
but just for read(display), can not write any eve files.
Bug3 can use polygon.txt to restore some feature of the program(eve.exe),
by commandLine "difc.exe polygon.txt", we can get eve_polygon.exe,
by commandLine "eve_polygon.exe tiger.eve",we will see normal figure now.
but just for read(display) too, can not write any eve files.
-------------- 2.limit of 42 corners -------------------------------------------
Bug2: The program assert points in single block is 14 corners(too few),
and they can be extened to another block(join another 28 corners) into a node.
So in paint_node(0040C6AD~0040CDCE), it only alloc 150h bytes for locate array,
and call combinepolyarrays(0040C48F~0040C4EA) to connect 2 blocks into 1 array.
In the combinepolyarrays(),
at 0040C49E~0040C4AD, it 1st copy 14 corners,
then goto extended block, to copy another 28 corners.
The codes are:
0040C4C0 eax=ebx+1C;//extended block
0040C4C3 mov ebx, eax
0040C4C5 mov ecx, 38h;//means 56(decimal)
0040C4CA do {mov eax, dword ptr [ebx]
0040C4CC mov dl, cl
0040C4CE and dl, 01
0040C4D1 if(!dl);jne 0040C4DA
0040C4D5 eax+=dword [edi+44];//base_x
0040C4D8 jmp 0040C4DD
0040C4DA else eax+=dword [edi+48];//base_y
0040C4DD mov dword ptr [esi], eax
0040C4DF add ebx, 4
0040C4E2 add esi, 4
0040C4E5 }while(ecx--);loop 0040C4CA
We chng the code to:
0040C4C0 87DF XCHG EDI,EBX
0040C4C2 87FE XCHG ESI,EDI
0040C4C4 8D76 1C LEA ESI,[ESI+1C];//extended block
0040C4C7 FC CLD
0040C4C8 8B8B F4000000 MOV ECX,DWORD PTR DS:[EBX+0F4];//corners_count
0040C4CE 83E9 0E SUB ECX,0E;//in 0040C49E~0040C4AD, it had copy 1st 14 points
0040C4D1 76 14 JBE SHORT 0040C4E7
0040C4D3 AD do {LODSD
0040C4D4 0343 44 ADD EAX,DWORD [EBX+44];//base_x
0040C4D7 AB STOSD
0040C4D8 AD LODSD
0040C4D9 0343 48 ADD EAX,DWORD [EBX+48];//base_y
0040C4DC AB STOSD
0040C4DD E2 F4 }while(ecx--);LOOP 0040C4D3
0040C4DF db 8 dup(90)
We put the above code in file offset(da9f~dac5).
============== 2.1.size and locate offset of array =====================
In paint_node(), its'origin code is
0040C6B0 81C444FEFFFF esp-=1BC
...
0040C736 8D955CFEFFFF edx=ebp-1A4;//offset(varray)
0040C73C call combinepolyarrays;//0040C48F
...
0040C760 8D9D5CFEFFFF ebx=ebp-1A4;//offset(varray)
0040C771 push ebx
0040C775 Call GDI32.Polygon
0040C7A4 ...
0040C7AA push ebx
0040C7AF Call GDI32.PolyBezier
0040C7C5
0040C7D4 8D9D5CFEFFFF ebx=ebp-1A4;//offset(varray)
0040C7DB push ebx
0040C7DF Call GDI32.Polygon
0040CB25 8D9D5CFEFFFF ebx=ebp-1a4;//offset(varray)
0040CB2F Call GDI32.CreatePolygonRgn
0040CC61 8D9D5CFEFFFF ebx=ebp-1A4;//offset(varray)
0040CC9D call painthandle
We chng the locate array from 150h bytes to 2100h bytes:
0040C6B0 81C444'dE'FFFF esp-=21BC
0040C736 8D955C'dE'FFFF edx=ebp-21A4;//offset(varray)
...
0040CC61 8D9D5C'dE'FFFF ebx=ebp-21A4;//offset(varray)
We put the above offset c6b3,c739,...cc64 in file offset(da8e~da99).
============== 2.2.size limit of array ===============================
so the sizeOfStackCommit of executable file(in file offset 124h),
must chng from 1000h to 4000h.
============== 2.3.check assert ======================================
And the program check the point whether in single block
at checkintegrity(0041DD0E~0041DFED),
of cause it can not in single block, the check is no use now,
we chng the code to:
0041DD0E E9DA02000090 jmp 41DFED
We put the above code in file offset(dacb~dad0).
============== 2.4.inject1 =======================================
Barry had compress his program,
we must move our code, after the program was unziped.
the origin code(file offset=11d9a~11da7) is
00450199 8BC1 MOV EAX,ECX
0045019B C1F9 02 SAR ECX,2
0045019E F3:A5 REP MOVSD
004501A0 03C8 ADD ECX,EAX
004501A2 AND ECX,3
004501A5 REP MOVSB
004501A7 JMP SHORT eve.004501cf
we chng the code to
00450199 8BC1 MOV EAX,ECX
0045019B F3:A4 REP MOVSB
0045019D E9 9FE4FBff jmp 0040e641
004501A2
============== 2.5.inject2 =======================================
...and change another block:
0040E641 BE 63E64000 MOV ESI,40E663
0040E646 BF 23054500 MOV EDI,450523
0040E64B B9 2B000000 MOV ECX,2B;//0045054e-00450523==2B
0040E650 F3:A4 REP MOVSB
0040E652 BF 7a124500 MOV EDI,45127a
0040E657 B9 90010000 MOV ECX,190
0040E65c F3:A4 REP MOVSB
0040E65e E9 6c1B0400 JMP eve.004501cf
0040E663
We put the above code in file offset(da41~da62).
00450523 FC CLD
00450524 BE 7a124500 MOV ESI,45127A;//file offset da8e, see 2.1
00450529 B8 00004000 MOV EAX,400000
0045052E B9 06000000 MOV ECX,6;//file[da8e~da99]={c6b3,c739,...cc64}
00450533 66:AD LODSW
00450535 C600 DE MOV BYTE PTR DS:[EAX],de
00450538 E2 F9 LOOP $-3
0045053A AC LODSB;//leng
0045053B 88C1 MOV CL,AL
0045053D 67:E3 07 JCXZ 450547
00450540 AD LODSD;//mem dst32
00450541 8b F8 mov edi,eax
00450543 F3:A4 REP MOVSB
;//file offset(da9f~dac5) -> mem(0040C4C0~0040C4E6),//see 2
;//file offset(dacb~dad0) -> mem(0041DD0E~0041DD13),//see 2.3
00450545 EB F3 JMP 45053A
We put the above code in file offset(da63~da8d).
============== 2.6.display =======================================
we had chng 150 bytes. we can save the eve.exe as eve_polyline.exe.
so you can open gandharva.eve by eve_polyline.exe now.
To prove we just modify about 150 bytes,
we can "fc /b eve.exe eve_polyline.exe > polyline.txt" to do
file-compare in binary mode. And we will get a text file,
which name is "polyline.txt", and its' content are:
'Comparing files eve.exe and eve_polyline.exe
00000125: 10 40
0000DA41: C6 BE
0000DA42: 45 63
...'
The bytes in column of eve_polyline.exe
are we just inputed.
If you had download a same eve 3.56,
after you notice bugs above, you can
1)send message to Barry...
but Barry had retired.
2)download the source code, compile by yourself...
even you maybe not a programer.
3)input "difc.exe polyline.txt" in console.
Of course, the name of file(polyline.txt) is not important.
-------------- 3.closeFigure without color logBrush --------------------------
After reWrite the import table of eve.exe(file offset=12228~1241a),
we can use api of gdi32.dll: BeginPath(),EndPath(),
CloseFigure(),StrokeAndFillPath().
Before use the apis, we need some logBrush and logPen.
in xpaint_update(00404A35~00404B74) and
xpaint_entire(00404D7D~00404EBB),
they use the same code to get logBrush or logPen.
the origin code is:
00404A35 C745E400000000 hBrushNew=0;//mov [ebp-1C], 0
00404A3C ....
;//(after CreatePen() and SelectObject(hPenNew))
00404B31 A3D8614200 old_hPen=eax;//mov dword ptr [004261D8], eax
00404B36 call update_line
00404B43 call GDI32.SelectObject(old_hpen)
00404B54 Call GDI32.DeleteObject(hPenNew)
00404B67 Call GDI32.SelectObject(old_hBrush)
00404B6F Call GDI32.DeleteObject(hBrushNew)
00404B74 8B5DE8 ebx=ebxsave;//dword ptr [ebp-18]
so we chng to
00404A35 E84D030000EBF4 call 00404D87/*createObj(),selectObj()*/, jmp 00404B77
...
00404B31 E95d020000 jmp 00404d93
...
00404B74 C3 90 90 ret
We put the above code in file offset(dad6~dadc),
(dae2~dae6),(daec~daf1)
============== 3.1.StrokeAndFillPath() =====================================
:00404D7D(E8 05 00 00 00) call 00404D87;//createObj(),selectObj()
:00404D82(e9 35 01 00 00) jmp 00404Ebc
:00404D87 C7 45 E4 00 00 00 00 hBrushNew=0;//mov [ebp-1C], 0
:00404D8e E9 a9 fc FF FF jmp 404A3c
:00404D93 A3D8614200 old_hPen=eax;//mov dword ptr [004261D8], eax
:00404D98 89E8 mov eax,ebp
:00404D9a 29e0 sub eax,esp
:00404D9c 3d 0010 0000 cmp eax,1000
:00404Da1 0f82 8ffdFFff jb 00404B36
:00404Da7 FF75 08 PUSH DWORD PTR SS:[ebp+08];hDC
:00404Daa FF15 04324500 CALL DWORD PTR DS:[453204];GDI32.StrokeAndFillPath
:00404Db0 e9 8efdFFff jmp 00404B43
We put the above code in file offset(daf7~db2e).
============== 3.2.CloseFigure() =========================================
in above 2.1.paint_node(),now we chng the code to:
0040C7A4 E9 0c86FFff 90 jmp 404Db5
We put the above code in file offset(db86~db8b)
:00404Db5 0BD2 7402 2BC2 if(edx)/*je $+4*/eax-=edx
:00404Dbb 8B8E D0000000 MOV ECX,DWORD PTR DS:[ESI+d0];nfillstyle
:00404Dc1 0BC9 OR ECX,ECX
:00404Dc3 0F84 e1790000 JE 0040C7AA;//normal Poly Bezier
:00404Dc9 50 PUSH EAX
:00404DcA 53 PUSH EBX
:00404DcB FF75 08 PUSH DWORD PTR SS:[ebp+08];/hDC
:00404Dce FF15 f8314500 CALL DWORD PTR DS:[4531f8]; GDI32.BeginPath
:00404Dd4 5B POP EBX
:00404Dd5 58 POP EAX
:00404Dd6 50 PUSH EAX; /Count
:00404Dd7 53 PUSH EBX; |pPoint
:00404Dd8 FF75 08 PUSH DWORD PTR SS:[ebp+08]; |hDC
:00404Ddb FF15 68304200 CALL GDI32.PolyBezier;dword ptr [00423068]
:00404De1 FF75 08 PUSH DWORD PTR SS:[ebp+08]; /hDC
:00404De4 FF15 00324500 CALL DWORD PTR DS:[453200];GDI32.CloseFigure
:00404Dea FF75 08 PUSH DWORD PTR SS:[ebp+08]; /hDC
:00404Ded FF15 40314500 CALL DWORD PTR DS:[4531fc];GDI32.EndPath
:00404Df3 E8 8fffFFFF call 00404D87;//createObj(),selectObj()
:00404Df8 E9 c8790000 jmp 0040C7C5
:00404DFD 0A dup(90)
We put the above code in file offset(db2f~db80).
============== 3.3.after word =======================================
we had chng 480 bytes. we can save the eve.exe as eve_polygon.exe.
so you can open tiger.eve by eve_polygon.exe now.
To prove we just modify about 480 bytes,
we can "fc /b eve.exe eve_polygon.exe > polygon.txt" to do
file-compare in binary mode. And we will get a text file,
which name is "polygon.txt", and its' content are:
'Comparing files eve.exe and eve_polygon.exe
00000125: 10 40
0000DA41: C6 BE
0000DA42: 45 63
...'
The bytes in column of eve_polygon.exe
are we just inputed.
If you had download a same eve 3.56,
after you notice bugs above, you can
1)send message to Barry...
but Barry had retired.
2)download the source code, compile by yourself...
even you maybe not a programer.
3)input "difc.exe polygon.txt" in console.
Of course, the name of file(polygon.txt) is not important.