Add more checks when input has lots of invalid metadata
This commit is contained in:
parent
6d45a3499f
commit
c8039d249e
|
@ -163,6 +163,8 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value getArg(Parameter arg) {
|
public Value getArg(Parameter arg) {
|
||||||
|
if (arg == null)
|
||||||
|
return new UnknownValue();
|
||||||
return getArg(arg.Index);
|
return getArg(arg.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,10 +175,12 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArg(Parameter arg, Value value) {
|
public void setArg(Parameter arg, Value value) {
|
||||||
|
if (arg != null)
|
||||||
setArg(arg.Index, value);
|
setArg(arg.Index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makeArgUnknown(Parameter arg) {
|
public void makeArgUnknown(Parameter arg) {
|
||||||
|
if (arg != null)
|
||||||
setArg(arg, getUnknownArg(arg.Index));
|
setArg(arg, getUnknownArg(arg.Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,14 +198,18 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value getLocal(Local local) {
|
public Value getLocal(Local local) {
|
||||||
|
if (local == null)
|
||||||
|
return new UnknownValue();
|
||||||
return getLocal(local.Index);
|
return getLocal(local.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocal(Local local, Value value) {
|
public void setLocal(Local local, Value value) {
|
||||||
|
if (local != null)
|
||||||
setLocal(local.Index, value);
|
setLocal(local.Index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makeLocalUnknown(Local local) {
|
public void makeLocalUnknown(Local local) {
|
||||||
|
if (local != null)
|
||||||
setLocal(local.Index, getUnknownLocal(local.Index));
|
setLocal(local.Index, getUnknownLocal(local.Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +255,7 @@ namespace de4dot.blocks.cflow {
|
||||||
case Code.Starg:
|
case Code.Starg:
|
||||||
case Code.Starg_S: emulate_Starg((Parameter)instr.Operand); break;
|
case Code.Starg_S: emulate_Starg((Parameter)instr.Operand); break;
|
||||||
case Code.Stloc:
|
case Code.Stloc:
|
||||||
case Code.Stloc_S: emulate_Stloc(((Local)instr.Operand).Index); break;
|
case Code.Stloc_S: emulate_Stloc((Local)instr.Operand); break;
|
||||||
case Code.Stloc_0: emulate_Stloc(0); break;
|
case Code.Stloc_0: emulate_Stloc(0); break;
|
||||||
case Code.Stloc_1: emulate_Stloc(1); break;
|
case Code.Stloc_1: emulate_Stloc(1); break;
|
||||||
case Code.Stloc_2: emulate_Stloc(2); break;
|
case Code.Stloc_2: emulate_Stloc(2); break;
|
||||||
|
@ -269,7 +277,7 @@ namespace de4dot.blocks.cflow {
|
||||||
case Code.Ldarga:
|
case Code.Ldarga:
|
||||||
case Code.Ldarga_S: emulate_Ldarga((Parameter)instr.Operand); break;
|
case Code.Ldarga_S: emulate_Ldarga((Parameter)instr.Operand); break;
|
||||||
case Code.Ldloca:
|
case Code.Ldloca:
|
||||||
case Code.Ldloca_S: emulate_Ldloca(((Local)instr.Operand).Index); break;
|
case Code.Ldloca_S: emulate_Ldloca((Local)instr.Operand); break;
|
||||||
|
|
||||||
case Code.Dup: valueStack.copyTop(); break;
|
case Code.Dup: valueStack.copyTop(); break;
|
||||||
|
|
||||||
|
@ -837,7 +845,11 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
void emulate_Starg(Parameter arg) {
|
void emulate_Starg(Parameter arg) {
|
||||||
setArg(arg.Index, valueStack.pop());
|
setArg(arg == null ? -1 : arg.Index, valueStack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
void emulate_Stloc(Local local) {
|
||||||
|
emulate_Stloc(local == null ? -1 : local.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emulate_Stloc(int index) {
|
void emulate_Stloc(int index) {
|
||||||
|
@ -849,6 +861,10 @@ namespace de4dot.blocks.cflow {
|
||||||
makeArgUnknown(arg);
|
makeArgUnknown(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emulate_Ldloca(Local local) {
|
||||||
|
emulate_Ldloca(local == null ? -1 : local.Index);
|
||||||
|
}
|
||||||
|
|
||||||
void emulate_Ldloca(int index) {
|
void emulate_Ldloca(int index) {
|
||||||
valueStack.pushUnknown();
|
valueStack.pushUnknown();
|
||||||
setLocal(index, getUnknownLocal(index));
|
setLocal(index, getUnknownLocal(index));
|
||||||
|
@ -867,7 +883,7 @@ namespace de4dot.blocks.cflow {
|
||||||
instr.CalculateStackUsage(out pushes, out pops);
|
instr.CalculateStackUsage(out pushes, out pops);
|
||||||
valueStack.pop(pops);
|
valueStack.pop(pops);
|
||||||
if (pushes == 1)
|
if (pushes == 1)
|
||||||
valueStack.push(getUnknownValue(method.MethodSig.RetType));
|
valueStack.push(getUnknownValue(method.MethodSig.GetRetType()));
|
||||||
else
|
else
|
||||||
valueStack.push(pushes);
|
valueStack.push(pushes);
|
||||||
}
|
}
|
||||||
|
@ -901,7 +917,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
void emulateLoadField(IField field) {
|
void emulateLoadField(IField field) {
|
||||||
if (field != null)
|
if (field != null)
|
||||||
valueStack.push(getUnknownValue(field.FieldSig.Type));
|
valueStack.push(getUnknownValue(field.FieldSig.GetFieldType()));
|
||||||
else
|
else
|
||||||
valueStack.pushUnknown();
|
valueStack.pushUnknown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,7 +435,7 @@ namespace de4dot.code {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
if (method.MethodSig.RetType.ElementType != ElementType.String && method.MethodSig.RetType.ElementType != ElementType.Object)
|
if (method.MethodSig.GetRetType().GetElementType() != ElementType.String && method.MethodSig.GetRetType().GetElementType() != ElementType.Object)
|
||||||
continue;
|
continue;
|
||||||
if (methodName != null && methodName != method.Name)
|
if (methodName != null && methodName != method.Name)
|
||||||
continue;
|
continue;
|
||||||
|
@ -664,6 +664,8 @@ namespace de4dot.code {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getMethodImplOptions(CustomAttribute cattr, ref int value) {
|
static bool getMethodImplOptions(CustomAttribute cattr, ref int value) {
|
||||||
|
if (cattr.IsRawBlob)
|
||||||
|
return false;
|
||||||
if (cattr.Arguments.Count != 1)
|
if (cattr.Arguments.Count != 1)
|
||||||
return false;
|
return false;
|
||||||
if (cattr.Arguments[0].Type.ElementType != ElementType.I2 &&
|
if (cattr.Arguments[0].Type.ElementType != ElementType.I2 &&
|
||||||
|
|
|
@ -204,7 +204,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var calledMethod = pushInstr.Operand as IMethod;
|
var calledMethod = pushInstr.Operand as IMethod;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
return null;
|
return null;
|
||||||
type = calledMethod.MethodSig.RetType;
|
type = calledMethod.MethodSig.GetRetType();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Newarr:
|
case Code.Newarr:
|
||||||
|
@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var field = pushInstr.Operand as IField;
|
var field = pushInstr.Operand as IField;
|
||||||
if (field == null || field.FieldSig == null)
|
if (field == null || field.FieldSig == null)
|
||||||
return null;
|
return null;
|
||||||
type = field.FieldSig.Type;
|
type = field.FieldSig.GetFieldType();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldflda:
|
case Code.Ldflda:
|
||||||
|
@ -278,7 +278,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var field2 = pushInstr.Operand as IField;
|
var field2 = pushInstr.Operand as IField;
|
||||||
if (field2 == null || field2.FieldSig == null)
|
if (field2 == null || field2.FieldSig == null)
|
||||||
return null;
|
return null;
|
||||||
type = createByReferenceType(field2.FieldSig.Type);
|
type = createByReferenceType(field2.FieldSig.GetFieldType());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldelema:
|
case Code.Ldelema:
|
||||||
|
|
|
@ -77,8 +77,11 @@ namespace de4dot.code.deobfuscators {
|
||||||
void init(IEnumerable<FieldDef> fields) {
|
void init(IEnumerable<FieldDef> fields) {
|
||||||
if (fields == null)
|
if (fields == null)
|
||||||
return;
|
return;
|
||||||
foreach (var field in fields)
|
foreach (var field in fields) {
|
||||||
add(field.FieldSig.Type.FullName);
|
var type = field.FieldSig.GetFieldType();
|
||||||
|
if (type != null)
|
||||||
|
add(type.FullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
if (!method.IsStatic || method.CilBody == null)
|
if (!method.IsStatic || method.CilBody == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool fixReturnType = isUnknownType(method.MethodSig.RetType);
|
bool fixReturnType = isUnknownType(method.MethodSig.GetRetType());
|
||||||
|
|
||||||
argInfos.Clear();
|
argInfos.Clear();
|
||||||
foreach (var arg in method.Parameters) {
|
foreach (var arg in method.Parameters) {
|
||||||
|
@ -433,7 +433,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, IField field) {
|
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, IField field) {
|
||||||
if (field == null || field.FieldSig == null)
|
if (field == null || field.FieldSig == null)
|
||||||
return false;
|
return false;
|
||||||
return addMethodArgType(gpp, methodParam, field.FieldSig.Type);
|
return addMethodArgType(gpp, methodParam, field.FieldSig.GetFieldType());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Local otherLocal) {
|
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Local otherLocal) {
|
||||||
|
@ -631,7 +631,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
|
|
||||||
var field = o as FieldDef;
|
var field = o as FieldDef;
|
||||||
if (field != null)
|
if (field != null)
|
||||||
return field.FieldSig != null && field.FieldSig.Type != null && field.FieldSig.Type.ElementType == ElementType.Object;
|
return field.FieldSig.GetFieldType().GetElementType() == ElementType.Object;
|
||||||
|
|
||||||
throw new ApplicationException(string.Format("Unknown type: {0}", o.GetType()));
|
throw new ApplicationException(string.Format("Unknown type: {0}", o.GetType()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ namespace de4dot.code.renamer {
|
||||||
if (param.IsReturnParameter)
|
if (param.IsReturnParameter)
|
||||||
Log.v("RetParam: {0} => {1}", Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName));
|
Log.v("RetParam: {0} => {1}", Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName));
|
||||||
else
|
else
|
||||||
Log.v("Param ({0}/{1}): {2} => {3}", param.ParameterDefinition.MethodSigIndex + 1, methodDef.MethodDef.MethodSig.Params.Count, Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName));
|
Log.v("Param ({0}/{1}): {2} => {3}", param.ParameterDefinition.MethodSigIndex + 1, methodDef.MethodDef.MethodSig.GetParamCount(), Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,6 +574,8 @@ namespace de4dot.code.renamer {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var sig = propMethod.MethodDef.MethodSig;
|
var sig = propMethod.MethodDef.MethodSig;
|
||||||
|
if (sig == null)
|
||||||
|
return null;
|
||||||
var propType = sig.RetType;
|
var propType = sig.RetType;
|
||||||
var propDef = createProperty(ownerType, name, propType, propMethod.MethodDef, null);
|
var propDef = createProperty(ownerType, name, propType, propMethod.MethodDef, null);
|
||||||
if (propDef == null)
|
if (propDef == null)
|
||||||
|
@ -601,7 +603,7 @@ namespace de4dot.code.renamer {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var sig = propMethod.MethodDef.MethodSig;
|
var sig = propMethod.MethodDef.MethodSig;
|
||||||
if (sig.Params.Count == 0)
|
if (sig == null || sig.Params.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
var propType = sig.Params[sig.Params.Count - 1];
|
var propType = sig.Params[sig.Params.Count - 1];
|
||||||
var propDef = createProperty(ownerType, name, propType, null, propMethod.MethodDef);
|
var propDef = createProperty(ownerType, name, propType, null, propMethod.MethodDef);
|
||||||
|
@ -1390,7 +1392,7 @@ namespace de4dot.code.renamer {
|
||||||
if (methodType == PropertyMethodType.Setter)
|
if (methodType == PropertyMethodType.Setter)
|
||||||
propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.Type;
|
propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.Type;
|
||||||
else
|
else
|
||||||
propType = propMethod.MethodDef.MethodSig.RetType;
|
propType = propMethod.MethodDef.MethodSig.GetRetType();
|
||||||
if (type == null)
|
if (type == null)
|
||||||
type = propType;
|
type = propType;
|
||||||
else if (!new SigComparer().Equals(type, propType))
|
else if (!new SigComparer().Equals(type, propType))
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace de4dot.code.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public string getNewPropertyName(PropertyDef propertyDefinition) {
|
public string getNewPropertyName(PropertyDef propertyDefinition) {
|
||||||
var propType = propertyDefinition.PropertySig.RetType;
|
var propType = propertyDefinition.PropertySig.GetRetType();
|
||||||
string newName;
|
string newName;
|
||||||
if (isGeneric(propType))
|
if (isGeneric(propType))
|
||||||
newName = existingPropertyNames.getName(propertyDefinition.Name, genericPropertyNameCreator);
|
newName = existingPropertyNames.getName(propertyDefinition.Name, genericPropertyNameCreator);
|
||||||
|
@ -145,7 +145,7 @@ namespace de4dot.code.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public string getNewFieldName(FieldDef field) {
|
public string getNewFieldName(FieldDef field) {
|
||||||
return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldSig.Type));
|
return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldSig.GetFieldType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string getNewFieldName(string oldName, INameCreator nameCreator) {
|
public string getNewFieldName(string oldName, INameCreator nameCreator) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
public MMethodDef(MethodDef methodDefinition, MTypeDef owner, int index)
|
public MMethodDef(MethodDef methodDefinition, MTypeDef owner, int index)
|
||||||
: base(methodDefinition, owner, index) {
|
: base(methodDefinition, owner, index) {
|
||||||
genericParams = MGenericParamDef.createGenericParamDefList(MethodDef.GenericParams);
|
genericParams = MGenericParamDef.createGenericParamDefList(MethodDef.GenericParams);
|
||||||
visibleBaseIndex = methodDefinition.MethodSig.HasThis ? 1 : 0;
|
visibleBaseIndex = methodDefinition.MethodSig != null && methodDefinition.MethodSig.HasThis ? 1 : 0;
|
||||||
for (int i = 0; i < methodDefinition.Parameters.Count; i++) {
|
for (int i = 0; i < methodDefinition.Parameters.Count; i++) {
|
||||||
var param = methodDefinition.Parameters[i];
|
var param = methodDefinition.Parameters[i];
|
||||||
if (param.IsNormalMethodParameter)
|
if (param.IsNormalMethodParameter)
|
||||||
|
|
|
@ -155,6 +155,8 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
var typeDef = resolver.resolveType(cattr.AttributeType);
|
var typeDef = resolver.resolveType(cattr.AttributeType);
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
continue;
|
continue;
|
||||||
|
if (cattr.NamedArguments == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int i = 0; i < cattr.NamedArguments.Count; i++) {
|
for (int i = 0; i < cattr.NamedArguments.Count; i++) {
|
||||||
var namedArg = cattr.NamedArguments[i];
|
var namedArg = cattr.NamedArguments[i];
|
||||||
|
@ -191,7 +193,7 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
foreach (var fieldDef in typeDef.AllFields) {
|
foreach (var fieldDef in typeDef.AllFields) {
|
||||||
if (fieldDef.FieldDef.Name != name)
|
if (fieldDef.FieldDef.Name != name)
|
||||||
continue;
|
continue;
|
||||||
if (new SigComparer().Equals(fieldDef.FieldDef.FieldSig.Type, fieldType))
|
if (new SigComparer().Equals(fieldDef.FieldDef.FieldSig.GetFieldType(), fieldType))
|
||||||
return fieldDef;
|
return fieldDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +209,7 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
foreach (var propDef in typeDef.AllProperties) {
|
foreach (var propDef in typeDef.AllProperties) {
|
||||||
if (propDef.PropertyDef.Name != name)
|
if (propDef.PropertyDef.Name != name)
|
||||||
continue;
|
continue;
|
||||||
if (new SigComparer().Equals(propDef.PropertyDef.PropertySig.RetType, propType))
|
if (new SigComparer().Equals(propDef.PropertyDef.PropertySig.GetRetType(), propType))
|
||||||
return propDef;
|
return propDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -373,6 +373,8 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
|
|
||||||
// Returns null if it's a non-loaded module/assembly
|
// Returns null if it's a non-loaded module/assembly
|
||||||
IEnumerable<Module> findModules(ITypeDefOrRef type) {
|
IEnumerable<Module> findModules(ITypeDefOrRef type) {
|
||||||
|
if (type == null)
|
||||||
|
return null;
|
||||||
var scope = type.Scope;
|
var scope = type.Scope;
|
||||||
if (scope == null)
|
if (scope == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -534,8 +534,8 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
|
|
||||||
foreach (var ifaceInfo in interfaces) {
|
foreach (var ifaceInfo in interfaces) {
|
||||||
foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) {
|
foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) {
|
||||||
if (methodsList.Count != 1) // Never happens
|
if (methodsList.Count < 1)
|
||||||
throw new ApplicationException("Interface with more than one method in the list");
|
continue;
|
||||||
var methodInst = methodsList[0];
|
var methodInst = methodsList[0];
|
||||||
var ifaceMethod = methodInst.origMethodDef;
|
var ifaceMethod = methodInst.origMethodDef;
|
||||||
if (!ifaceMethod.isVirtual())
|
if (!ifaceMethod.isVirtual())
|
||||||
|
@ -569,8 +569,8 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
}
|
}
|
||||||
foreach (var ifaceInfo in allImplementedInterfaces.Keys) {
|
foreach (var ifaceInfo in allImplementedInterfaces.Keys) {
|
||||||
foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) {
|
foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) {
|
||||||
if (methodsList.Count != 1) // Never happens
|
if (methodsList.Count < 1)
|
||||||
throw new ApplicationException("Interface with more than one method in the list");
|
continue;
|
||||||
var ifaceMethod = methodsList[0].origMethodDef;
|
var ifaceMethod = methodsList[0].origMethodDef;
|
||||||
if (!ifaceMethod.isVirtual())
|
if (!ifaceMethod.isVirtual())
|
||||||
continue;
|
continue;
|
||||||
|
@ -690,6 +690,8 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberRef simpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) {
|
MemberRef simpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) {
|
||||||
|
if (module == null)
|
||||||
|
return new MemberRefUser(null, methodRef.Name, methodRef.MethodSig, declaringType);
|
||||||
var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType);
|
var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType);
|
||||||
return module.ModuleDefMD.UpdateRowId(mr);
|
return module.ModuleDefMD.UpdateRowId(mr);
|
||||||
}
|
}
|
||||||
|
|
2
dot10
2
dot10
|
@ -1 +1 @@
|
||||||
Subproject commit 83714ec1536ec43ca5dd1ef139f767e20902cd02
|
Subproject commit d7ccb50d4ea85a48c05132dff8ae1e38c4dcbba2
|
Loading…
Reference in New Issue
Block a user