176 lines
6.1 KiB
Diff
176 lines
6.1 KiB
Diff
|
diff --git a/NEWS b/NEWS
|
||
|
index 129d55fe..7eb256ca 100644
|
||
|
--- a/NEWS
|
||
|
+++ b/NEWS
|
||
|
@@ -43,6 +43,11 @@
|
||
|
with empty acts (NULL act->p.String). Perform deep copy in pushdup,
|
||
|
instead of shallow copy (issue #121).
|
||
|
* Fix heap-buffer-overflow in getString (CVE-2018-7867, issue #116).
|
||
|
+ * Fix null pointer dereference in getInt (CVE-2018-9132, issue #133).
|
||
|
+ * Fix heap-use-after-free in decompileJUMP (CVE-2018-9009, issue #131).
|
||
|
+ * Fix memory exhaustion in parseSWF_ACTIONRECORD (CVE-2018-7876, #109).
|
||
|
+ * Fix heap-buffer-overflow in function getString (CVE-2018-7873, #111).
|
||
|
+ * Fix null pointer dereference in newVar3 (CVE-2018-7866, #118).
|
||
|
|
||
|
0.4.8 - 2017-04-07
|
||
|
|
||
|
diff --git a/util/decompile.c b/util/decompile.c
|
||
|
index e9341356..cf1a372d 100644
|
||
|
--- a/util/decompile.c
|
||
|
+++ b/util/decompile.c
|
||
|
@@ -358,9 +358,19 @@ getString(struct SWF_ACTIONPUSHPARAM *act)
|
||
|
return t;
|
||
|
}
|
||
|
case PUSH_INT: /* INTEGER */
|
||
|
- t=malloc(10); /* 32-bit decimal */
|
||
|
- sprintf(t,"%ld", act->p.Integer );
|
||
|
+ {
|
||
|
+ char length_finder[1];
|
||
|
+ int needed_length = snprintf(length_finder, 1, "%ld", act->p.Integer) + 1;
|
||
|
+ if (needed_length <= 0)
|
||
|
+ {
|
||
|
+ SWF_warn("WARNING: could not evaluate size of buffer (memory issue ?).\n");
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ t = malloc(needed_length);
|
||
|
+ sprintf(t, "%ld", act->p.Integer );
|
||
|
return t;
|
||
|
+ }
|
||
|
case PUSH_CONSTANT: /* CONSTANT8 */
|
||
|
if (act->p.Constant8 > poolcounter)
|
||
|
{
|
||
|
@@ -387,7 +397,14 @@ getString(struct SWF_ACTIONPUSHPARAM *act)
|
||
|
case 12:
|
||
|
case 11: /* INCREMENTED or DECREMENTED VARIABLE */
|
||
|
case PUSH_VARIABLE: /* VARIABLE */
|
||
|
- return act->p.String;
|
||
|
+ if (!act->p.String)
|
||
|
+ {
|
||
|
+ SWF_warn("WARNING: Call to getString with PUSH_VARIABLE defining NULL string.\n");
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ t=malloc(strlen(act->p.String)+1); /* NULL character */
|
||
|
+ strcpy(t,act->p.String);
|
||
|
+ return t;
|
||
|
default:
|
||
|
fprintf (stderr," Can't get string for type: %d\n", act->Type);
|
||
|
break;
|
||
|
@@ -481,7 +498,15 @@ getInt(struct SWF_ACTIONPUSHPARAM *act)
|
||
|
case PUSH_NULL: /* NULL */
|
||
|
return 0;
|
||
|
case PUSH_REGISTER: /* REGISTER */
|
||
|
- return getInt(regs[act->p.RegisterNumber]);
|
||
|
+ if (regs[act->p.RegisterNumber])
|
||
|
+ {
|
||
|
+ return getInt(regs[act->p.RegisterNumber]);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ SWF_warn("WARNING: retrieving undefined register values.\n");
|
||
|
+ break;
|
||
|
+ }
|
||
|
case PUSH_DOUBLE: /* DOUBLE */
|
||
|
return (int)act->p.Double;
|
||
|
case PUSH_INT: /* INTEGER */
|
||
|
@@ -939,6 +964,24 @@ decompileGETURL2 (SWF_ACTION *act)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static inline int Offset(SWF_ACTION *actions, int n, int maxn)
|
||
|
+{
|
||
|
+ if(!n || n >= maxn)
|
||
|
+ {
|
||
|
+#if DEBUG
|
||
|
+ SWF_warn("Offset: want %i, max %i\n", n, maxn);
|
||
|
+#endif
|
||
|
+ return -999;
|
||
|
+ } else if (n < 1) {
|
||
|
+
|
||
|
+#if DEBUG
|
||
|
+ SWF_warn("Offset: want %i < 1\n", n);
|
||
|
+#endif
|
||
|
+ return -998;
|
||
|
+ }
|
||
|
+ return actions[n].SWF_ACTIONRECORD.Offset;
|
||
|
+}
|
||
|
+
|
||
|
static inline int OpCode(SWF_ACTION *actions, int n, int maxn)
|
||
|
{
|
||
|
if(!n || n >= maxn)
|
||
|
@@ -1929,7 +1972,7 @@ decompileJUMP(int n, SWF_ACTION *actions, int maxn)
|
||
|
{
|
||
|
sactif = (struct SWF_ACTIONIF *)&(actions[n+i+j]);
|
||
|
/* chk whether last jump does lead us back to start of loop */
|
||
|
- if (sactif->Actions[sactif->numActions-1].SWF_ACTIONRECORD.ActionCode==SWFACTION_JUMP
|
||
|
+ if (OpCode(sactif->Actions, sactif->numActions-1, maxn) == SWFACTION_JUMP
|
||
|
&& sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.BranchOffset+
|
||
|
sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.Offset==
|
||
|
actions[n].SWF_ACTIONRECORD.Offset )
|
||
|
@@ -2101,7 +2144,7 @@ decompile_SWITCH(int n, SWF_ACTION *actions, int maxn, int off1end)
|
||
|
int offSave;
|
||
|
for (i=0; i<n_firstactions; i++) // seek last op in 1st if
|
||
|
{
|
||
|
- if (actions[i+1].SWF_ACTIONRECORD.Offset==off1end)
|
||
|
+ if (Offset(actions, i+1, maxn) == off1end)
|
||
|
{
|
||
|
// println("found #off end first= %d",i+1);
|
||
|
if (OpCode(actions, i, maxn) == SWFACTION_JUMP)
|
||
|
@@ -2334,7 +2377,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
|
||
|
* that points to a JUMP above the IF statement.
|
||
|
*/
|
||
|
if(n && isLogicalOp(n-1, actions, maxn) &&
|
||
|
- (sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
|
||
|
+ (OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
|
||
|
( (sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.Offset +
|
||
|
sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset) < actions[n].SWF_ACTIONRECORD.Offset) &&
|
||
|
isLogicalOp(sact->numActions-2, sact->Actions, maxn) )
|
||
|
@@ -2424,7 +2467,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
|
||
|
*/
|
||
|
|
||
|
if( isLogicalOp(n-1, actions, maxn) &&
|
||
|
- ( (sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
|
||
|
+ ((OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
|
||
|
sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset < 0) )
|
||
|
{
|
||
|
if(0) dumpRegs();
|
||
|
@@ -2460,7 +2503,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
|
||
|
}
|
||
|
{ // WTF ???
|
||
|
#define SOME_IF_DEBUG 0 /* coders only */
|
||
|
- int has_else_or_break= ((sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
|
||
|
+ int has_else_or_break= ((OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
|
||
|
(sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset > 0 )) ? 1:0;
|
||
|
int has_lognot=(OpCode(actions, n-1, maxn) == SWFACTION_LOGICALNOT) ? 1:0;
|
||
|
int else_action_cnt=0,is_logor=0,is_logand=0,sbi,sbe;
|
||
|
@@ -3154,7 +3197,7 @@ decompileSETTARGET(int n, SWF_ACTION *actions, int maxn, int is_type2)
|
||
|
{
|
||
|
INDENT
|
||
|
println("tellTarget('%s') {" ,name);
|
||
|
- while(action_cnt+n<maxn)
|
||
|
+ for (; action_cnt+n < maxn-1; action_cnt++)
|
||
|
{
|
||
|
if (OpCode(actions, n+1+action_cnt, maxn)==SWFACTION_SETTARGET
|
||
|
|| OpCode(actions, n+1+action_cnt, maxn)==SWFACTION_SETTARGET2
|
||
|
@@ -3164,7 +3207,6 @@ decompileSETTARGET(int n, SWF_ACTION *actions, int maxn, int is_type2)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
- action_cnt++;
|
||
|
}
|
||
|
decompileActions(action_cnt,&actions[n+1],gIndent+1);
|
||
|
INDENT
|
||
|
diff --git a/util/swftypes.h b/util/swftypes.h
|
||
|
index fe80eb2c..9648c628 100644
|
||
|
--- a/util/swftypes.h
|
||
|
+++ b/util/swftypes.h
|
||
|
@@ -363,7 +363,7 @@ struct SWF_ACTIONDEFINEFUNCTION {
|
||
|
UI16 Length;
|
||
|
UI32 Offset;
|
||
|
STRING FunctionName;
|
||
|
- WORD NumParams;
|
||
|
+ UI16 NumParams;
|
||
|
STRING *Params;
|
||
|
WORD CodeSize;
|
||
|
int numActions;
|